---
CHANGELOG.md | 2 +
modules/default/weather/current.njk | 13 ++-
modules/default/weather/forecast.njk | 17 ++--
modules/default/weather/hourly.njk | 17 ++--
.../default/weather/providers/envcanada.js | 33 ++------
.../default/weather/providers/openmeteo.js | 12 +--
.../weather/providers/openweathermap.js | 83 +++++--------------
.../weather/providers/pirateweather.js | 9 +-
modules/default/weather/providers/smhi.js | 10 +--
.../default/weather/providers/ukmetoffice.js | 4 +-
.../weather/providers/ukmetofficedatahub.js | 4 +-
.../default/weather/providers/weatherbit.js | 3 +-
.../default/weather/providers/weatherflow.js | 1 +
.../default/weather/providers/weathergov.js | 22 ++---
modules/default/weather/providers/yr.js | 14 ++--
modules/default/weather/weather.js | 9 +-
modules/default/weather/weatherobject.js | 5 +-
modules/default/weather/weatherutils.js | 21 +++++
.../modules/weather/forecastweather_units.js | 3 +-
.../hourlyweather_showPrecipitation.js | 27 ++++++
tests/e2e/modules/weather_forecast_spec.js | 27 ++++--
tests/e2e/modules/weather_hourly_spec.js | 28 +++++++
tests/mocks/weather_forecast.json | 4 +-
.../default/weather/weather_utils_spec.js | 45 ++++++++++
translations/cs.json | 2 +-
translations/da.json | 2 +-
translations/de.json | 3 +-
translations/en.json | 3 +-
translations/es.json | 2 +-
translations/fi.json | 2 +-
translations/fr.json | 2 +-
translations/gl.json | 2 +-
translations/gu.json | 2 +-
translations/he.json | 2 +-
translations/hi.json | 2 +-
translations/ko.json | 2 +-
translations/lt.json | 2 +-
translations/nb.json | 2 +
translations/nl.json | 2 +-
translations/pl.json | 2 +-
translations/pt-br.json | 2 +-
translations/pt.json | 2 +-
translations/tr.json | 2 +-
translations/uk.json | 2 +-
translations/zh-tw.json | 2 +-
45 files changed, 265 insertions(+), 192 deletions(-)
create mode 100644 tests/configs/modules/weather/hourlyweather_showPrecipitation.js
create mode 100644 tests/unit/modules/default/weather/weather_utils_spec.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ccd82d46..3964da9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,8 @@ _This release is scheduled to be released on 2023-04-01._
- Use develop as target branch for dependabot
- Update issue template and contributing doc
+- The weather modules clearly separates precipation amount and probability (risk of rain/snow)
+ - This requires all providers that only supports probability to change the config from `showPrecipitationAmount` to `showPrecipitationProbability`.
- Update weather tests
- Changed updatenotification module for MagicMirror repo only: Send only notifications for `master` if there is a tag on a newer commit
- Update dates in Calendar widgets every minute
diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk
index db6eac77..0459a135 100644
--- a/modules/default/weather/current.njk
+++ b/modules/default/weather/current.njk
@@ -54,16 +54,21 @@
{% endif %}
- {% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %}
+ {% if (config.showFeelsLike or config.showPrecipitationAmount or config.showPrecipitationProbability) and not config.onlyTemp %}
{% if config.showFeelsLike %}
{{ "FEELS" | translate({DEGREE: current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }) }}
-
+
{% endif %}
- {% if config.showPrecipitationAmount %}
+ {% if config.showPrecipitationAmount and current.precipitationAmount %}
- {{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }}
+ {{ "PRECIP_AMOUNT" | translate }} {{ current.precipitationAmount | unit("precip", current.precipitationUnits) }}
+
+ {% endif %}
+ {% if config.showPrecipitationProbability and current.precipitationProbability %}
+
+ {{ "PRECIP_POP" | translate }} {{ current.precipitationProbability }}%
{% endif %}
diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk
index 2bac7eae..aa0ac8b4 100644
--- a/modules/default/weather/forecast.njk
+++ b/modules/default/weather/forecast.njk
@@ -23,15 +23,14 @@
{{ f.minTemperature | roundValue | unit("temperature") | decimalSymbol }}
{% if config.showPrecipitationAmount %}
- {% if f.precipitationUnits %}
-
- {{ f.precipitation }}{{ f.precipitationUnits }}
- |
- {% else %}
-
- {{ f.precipitation | unit("precip") }}
- |
- {% endif %}
+
+ {{ f.precipitationAmount | unit("precip", f.precipitationUnits) }}
+ |
+ {% endif %}
+ {% if config.showPrecipitationProbability %}
+
+ {{ f.precipitationProbability }}%
+ |
{% endif %}
{% set currentStep = currentStep + 1 %}
diff --git a/modules/default/weather/hourly.njk b/modules/default/weather/hourly.njk
index f58d31a0..2904e516 100644
--- a/modules/default/weather/hourly.njk
+++ b/modules/default/weather/hourly.njk
@@ -11,15 +11,14 @@
{{ hour.temperature | roundValue | unit("temperature") }}
{% if config.showPrecipitationAmount %}
- {% if hour.precipitationUnits %}
-
- {{ hour.precipitation }}{{ hour.precipitationUnits }}
- |
- {% else %}
-
- {{ hour.precipitation | unit("precip") }}
- |
- {% endif %}
+
+ {{ hour.precipitationAmount | unit("precip", hour.precipitationUnits) }}
+ |
+ {% endif %}
+ {% if config.showPrecipitationProbability %}
+
+ {{ hour.precipitationProbability }}%
+ |
{% endif %}
{% set currentStep = currentStep + 1 %}
diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js
index b4bd4835..941edf8f 100644
--- a/modules/default/weather/providers/envcanada.js
+++ b/modules/default/weather/providers/envcanada.js
@@ -230,12 +230,7 @@ WeatherProvider.register("envcanada", {
const foreGroup = ECdoc.querySelectorAll("siteData forecastGroup forecast");
- // For simplicity, we will only accumulate precipitation and will not try to break out
- // rain vs snow accumulations
-
- weather.rain = null;
- weather.snow = null;
- weather.precipitation = null;
+ weather.precipitationAmount = null;
//
// The EC forecast is held in a 12-element array - Elements 0 to 11 - with each day encompassing
@@ -343,9 +338,7 @@ WeatherProvider.register("envcanada", {
this.setMinMaxTemps(weather, foreGroup, stepDay, true, currentTemp);
- weather.rain = null;
- weather.snow = null;
- weather.precipitation = null;
+ weather.precipitationAmount = null;
this.setPrecipitation(weather, foreGroup, stepDay);
@@ -402,8 +395,7 @@ WeatherProvider.register("envcanada", {
const precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0;
if (precipLOP > 0) {
- weather.precipitation = precipLOP;
- weather.precipitationUnits = hourGroup[stepHour].querySelector("lop").getAttribute("units");
+ weather.precipitationProbability = precipLOP;
}
//
@@ -508,27 +500,14 @@ WeatherProvider.register("envcanada", {
setPrecipitation(weather, foreGroup, today) {
if (foreGroup[today].querySelector("precipitation accumulation")) {
- weather.precipitation = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0;
-
- weather.precipitationUnits = " " + foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units");
-
- if (this.config.units === "imperial") {
- if (weather.precipitationUnits === " cm") {
- weather.precipitation = (weather.precipitation * 0.394).toFixed(2);
- weather.precipitationUnits = " in";
- }
- if (weather.precipitationUnits === " mm") {
- weather.precipitation = (weather.precipitation * 0.0394).toFixed(2);
- weather.precipitationUnits = " in";
- }
- }
+ weather.precipitationAmount = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0;
+ weather.precipitationUnits = foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units");
}
// Check Today element for POP
if (foreGroup[today].querySelector("abbreviatedForecast pop").textContent > 0) {
- weather.precipitation = foreGroup[today].querySelector("abbreviatedForecast pop").textContent;
- weather.precipitationUnits = foreGroup[today].querySelector("abbreviatedForecast pop").getAttribute("units");
+ weather.precipitationProbability = foreGroup[today].querySelector("abbreviatedForecast pop").textContent;
}
},
diff --git a/modules/default/weather/providers/openmeteo.js b/modules/default/weather/providers/openmeteo.js
index 0810d48b..3676b6e2 100644
--- a/modules/default/weather/providers/openmeteo.js
+++ b/modules/default/weather/providers/openmeteo.js
@@ -367,7 +367,7 @@ WeatherProvider.register("openmeteo", {
* `current_weather` object.
*/
const h = moment().hour();
- const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+ const currentWeather = new WeatherObject();
currentWeather.date = weather.current_weather.time;
currentWeather.windSpeed = weather.current_weather.windspeed;
@@ -381,7 +381,7 @@ WeatherProvider.register("openmeteo", {
currentWeather.humidity = parseFloat(weather.hourly[h].relativehumidity_2m);
currentWeather.rain = parseFloat(weather.hourly[h].rain);
currentWeather.snow = parseFloat(weather.hourly[h].snowfall * 10);
- currentWeather.precipitation = parseFloat(weather.hourly[h].precipitation);
+ currentWeather.precipitationAmount = parseFloat(weather.hourly[h].precipitation);
return currentWeather;
},
@@ -391,7 +391,7 @@ WeatherProvider.register("openmeteo", {
const days = [];
weathers.daily.forEach((weather, i) => {
- const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+ const currentWeather = new WeatherObject();
currentWeather.date = weather.time;
currentWeather.windSpeed = weather.windspeed_10m_max;
@@ -404,7 +404,7 @@ WeatherProvider.register("openmeteo", {
currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime());
currentWeather.rain = parseFloat(weather.rain_sum);
currentWeather.snow = parseFloat(weather.snowfall_sum * 10);
- currentWeather.precipitation = parseFloat(weather.precipitation_sum);
+ currentWeather.precipitationAmount = parseFloat(weather.precipitation_sum);
days.push(currentWeather);
});
@@ -422,7 +422,7 @@ WeatherProvider.register("openmeteo", {
return;
}
- const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+ const currentWeather = new WeatherObject();
const h = Math.ceil((i + 1) / 24) - 1;
currentWeather.date = weather.time;
@@ -437,7 +437,7 @@ WeatherProvider.register("openmeteo", {
currentWeather.humidity = parseFloat(weather.relativehumidity_2m);
currentWeather.rain = parseFloat(weather.rain);
currentWeather.snow = parseFloat(weather.snowfall * 10);
- currentWeather.precipitation = parseFloat(weather.precipitation);
+ currentWeather.precipitationAmount = parseFloat(weather.precipitation);
hours.push(currentWeather);
});
diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js
index 6a22032a..36d80b69 100644
--- a/modules/default/weather/providers/openweathermap.js
+++ b/modules/default/weather/providers/openweathermap.js
@@ -186,7 +186,7 @@ WeatherProvider.register("openweathermap", {
weather.maxTemperature = Math.max.apply(null, maxTemp);
weather.rain = rain;
weather.snow = snow;
- weather.precipitation = weather.rain + weather.snow;
+ weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0);
// push weather information to days array
days.push(weather);
// create new weather-object
@@ -216,20 +216,12 @@ WeatherProvider.register("openweathermap", {
minTemp.push(forecast.main.temp_min);
maxTemp.push(forecast.main.temp_max);
- if (forecast.hasOwnProperty("rain")) {
- if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) {
- rain += forecast.rain["3h"] / 25.4;
- } else if (!isNaN(forecast.rain["3h"])) {
- rain += forecast.rain["3h"];
- }
+ if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain["3h"])) {
+ rain += forecast.rain["3h"];
}
- if (forecast.hasOwnProperty("snow")) {
- if (this.config.units === "imperial" && !isNaN(forecast.snow["3h"])) {
- snow += forecast.snow["3h"] / 25.4;
- } else if (!isNaN(forecast.snow["3h"])) {
- snow += forecast.snow["3h"];
- }
+ if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow["3h"])) {
+ snow += forecast.snow["3h"];
}
}
@@ -239,7 +231,7 @@ WeatherProvider.register("openweathermap", {
weather.maxTemperature = Math.max.apply(null, maxTemp);
weather.rain = rain;
weather.snow = snow;
- weather.precipitation = weather.rain + weather.snow;
+ weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0);
// push weather information to days array
days.push(weather);
return days.slice(1);
@@ -264,25 +256,18 @@ WeatherProvider.register("openweathermap", {
// forecast.rain not available if amount is zero
// The API always returns in millimeters
- if (forecast.hasOwnProperty("rain")) {
- if (this.config.units === "imperial" && !isNaN(forecast.rain)) {
- weather.rain = forecast.rain / 25.4;
- } else if (!isNaN(forecast.rain)) {
- weather.rain = forecast.rain;
- }
+ if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain)) {
+ weather.rain = forecast.rain;
}
// forecast.snow not available if amount is zero
// The API always returns in millimeters
- if (forecast.hasOwnProperty("snow")) {
- if (this.config.units === "imperial" && !isNaN(forecast.snow)) {
- weather.snow = forecast.snow / 25.4;
- } else if (!isNaN(forecast.snow)) {
- weather.snow = forecast.snow;
- }
+ if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow)) {
+ weather.snow = forecast.snow;
}
- weather.precipitation = weather.rain + weather.snow;
+ weather.precipitationAmount = weather.rain + weather.snow;
+ weather.precipitationProbability = forecast.pop ? forecast.pop * 100 : undefined;
days.push(weather);
}
@@ -310,23 +295,15 @@ WeatherProvider.register("openweathermap", {
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"];
- }
+ 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"];
- }
+ current.snow = data.current["snow"]["1h"];
precip = true;
}
if (precip) {
- current.precipitation = current.rain + current.snow;
+ current.precipitationAmount = (current.rain ?? 0) + (current.snow ?? 0);
}
current.feelsLikeTemp = data.current.feels_like;
}
@@ -344,25 +321,18 @@ WeatherProvider.register("openweathermap", {
weather.windSpeed = hour.wind_speed;
weather.windFromDirection = hour.wind_deg;
weather.weatherType = this.convertWeatherType(hour.weather[0].icon);
+ weather.precipitationProbability = hour.pop ? hour.pop * 100 : undefined;
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"];
- }
+ 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"];
- }
+ weather.snow = hour.snow["1h"];
precip = true;
}
if (precip) {
- weather.precipitation = weather.rain + weather.snow;
+ weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0);
}
hours.push(weather);
@@ -383,25 +353,18 @@ WeatherProvider.register("openweathermap", {
weather.windSpeed = day.wind_speed;
weather.windFromDirection = day.wind_deg;
weather.weatherType = this.convertWeatherType(day.weather[0].icon);
+ weather.precipitationProbability = day.pop ? day.pop * 100 : undefined;
precip = false;
if (!isNaN(day.rain)) {
- if (this.config.units === "imperial") {
- weather.rain = day.rain / 25.4;
- } else {
- weather.rain = day.rain;
- }
+ 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;
- }
+ weather.snow = day.snow;
precip = true;
}
if (precip) {
- weather.precipitation = weather.rain + weather.snow;
+ weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0);
}
days.push(weather);
diff --git a/modules/default/weather/providers/pirateweather.js b/modules/default/weather/providers/pirateweather.js
index a08a7996..1bb95611 100644
--- a/modules/default/weather/providers/pirateweather.js
+++ b/modules/default/weather/providers/pirateweather.js
@@ -94,16 +94,11 @@ WeatherProvider.register("pirateweather", {
weather.rain = 0;
let precip = 0;
- // The API will return centimeters if units is 'si' and will return inches for 'us'
if (forecast.hasOwnProperty("precipAccumulation")) {
- if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) {
- precip = forecast.precipAccumulation;
- } else if (!isNaN(forecast.precipAccumulation)) {
- precip = forecast.precipAccumulation * 10;
- }
+ precip = forecast.precipAccumulation * 10;
}
- weather.precipitation = precip;
+ weather.precipitationAmount = precip;
if (forecast.hasOwnProperty("precipType")) {
if (forecast.precipType === "snow") {
weather.snow = precip;
diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js
index 719adafd..d92893d9 100644
--- a/modules/default/weather/providers/smhi.js
+++ b/modules/default/weather/providers/smhi.js
@@ -157,19 +157,19 @@ WeatherProvider.register("smhi", {
// 0 = No precipitation
case 1: // Snow
currentWeather.snow += precipitationValue;
- currentWeather.precipitation += precipitationValue;
+ currentWeather.precipitationAmount += precipitationValue;
break;
case 2: // Snow and rain, treat it as 50/50 snow and rain
currentWeather.snow += precipitationValue / 2;
currentWeather.rain += precipitationValue / 2;
- currentWeather.precipitation += precipitationValue;
+ currentWeather.precipitationAmount += precipitationValue;
break;
case 3: // Rain
case 4: // Drizzle
case 5: // Freezing rain
case 6: // Freezing drizzle
currentWeather.rain += precipitationValue;
- currentWeather.precipitation += precipitationValue;
+ currentWeather.precipitationAmount += precipitationValue;
break;
}
@@ -202,7 +202,7 @@ WeatherProvider.register("smhi", {
currentWeather.maxTemperature = -Infinity;
currentWeather.snow = 0;
currentWeather.rain = 0;
- currentWeather.precipitation = 0;
+ currentWeather.precipitationAmount = 0;
result.push(currentWeather);
}
@@ -221,7 +221,7 @@ WeatherProvider.register("smhi", {
currentWeather.maxTemperature = Math.max(currentWeather.maxTemperature, weatherObject.temperature);
currentWeather.snow += weatherObject.snow;
currentWeather.rain += weatherObject.rain;
- currentWeather.precipitation += weatherObject.precipitation;
+ currentWeather.precipitationAmount += weatherObject.precipitationAmount;
}
return result;
diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js
index 3b61f66c..9a1559f3 100644
--- a/modules/default/weather/providers/ukmetoffice.js
+++ b/modules/default/weather/providers/ukmetoffice.js
@@ -100,7 +100,7 @@ WeatherProvider.register("ukmetoffice", {
currentWeather.humidity = rep.H;
currentWeather.temperature = rep.T;
currentWeather.feelsLikeTemp = rep.F;
- currentWeather.precipitation = parseInt(rep.Pp);
+ currentWeather.precipitationProbability = parseInt(rep.Pp);
currentWeather.windSpeed = WeatherUtils.convertWindToMetric(rep.S);
currentWeather.windFromDirection = WeatherUtils.convertWindDirection(rep.D);
currentWeather.weatherType = this.convertWeatherType(rep.W);
@@ -138,7 +138,7 @@ WeatherProvider.register("ukmetoffice", {
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);
+ weather.precipitationProbability = parseInt(period.Rep[0].PPd);
days.push(weather);
}
diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js
index 229167d8..5bb8e9c9 100644
--- a/modules/default/weather/providers/ukmetofficedatahub.js
+++ b/modules/default/weather/providers/ukmetofficedatahub.js
@@ -134,7 +134,7 @@ WeatherProvider.register("ukmetofficedatahub", {
currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity;
currentWeather.rain = forecastDataHours[hour].totalPrecipAmount;
currentWeather.snow = forecastDataHours[hour].totalSnowAmount;
- currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation;
+ currentWeather.precipitationProbability = forecastDataHours[hour].probOfPrecipitation;
currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature;
// Pass on full details, so they can be used in custom templates
@@ -206,7 +206,7 @@ WeatherProvider.register("ukmetofficedatahub", {
forecastWeather.windSpeed = forecastDataDays[day].midday10MWindSpeed;
forecastWeather.windFromDirection = forecastDataDays[day].midday10MWindDirection;
forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode);
- forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation;
+ forecastWeather.precipitationProbability = forecastDataDays[day].dayProbabilityOfPrecipitation;
forecastWeather.temperature = forecastDataDays[day].dayMaxScreenTemperature;
forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity;
forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain;
diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js
index 8db1c528..10a85a11 100644
--- a/modules/default/weather/providers/weatherbit.js
+++ b/modules/default/weather/providers/weatherbit.js
@@ -125,7 +125,8 @@ WeatherProvider.register("weatherbit", {
weather.date = moment(forecast.datetime, "YYYY-MM-DD");
weather.minTemperature = forecast.min_temp;
weather.maxTemperature = forecast.max_temp;
- weather.precipitation = forecast.precip;
+ weather.precipitationAmount = forecast.precip;
+ weather.precipitationProbability = forecast.pop;
weather.weatherType = this.convertWeatherType(forecast.weather.icon);
days.push(weather);
diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js
index f9f045eb..aecfb63e 100644
--- a/modules/default/weather/providers/weatherflow.js
+++ b/modules/default/weather/providers/weatherflow.js
@@ -55,6 +55,7 @@ WeatherProvider.register("weatherflow", {
weather.date = moment.unix(forecast.day_start_local);
weather.minTemperature = forecast.air_temp_low;
weather.maxTemperature = forecast.air_temp_high;
+ weather.precipitationProbability = forecast.precip_probability;
weather.weatherType = forecast.icon;
weather.snow = 0;
diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js
index 7d9640ec..7e327c79 100644
--- a/modules/default/weather/providers/weathergov.js
+++ b/modules/default/weather/providers/weathergov.js
@@ -210,9 +210,7 @@ WeatherProvider.register("weathergov", {
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);
+ currentWeather.precipitationAmount = currentWeatherData.precipitationLastHour.value;
if (currentWeatherData.heatIndex.value !== null) {
currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value;
} else if (currentWeatherData.windChill.value !== null) {
@@ -240,6 +238,8 @@ WeatherProvider.register("weathergov", {
* fetch forecast information for daily forecast.
*/
fetchForecastDaily(forecasts) {
+ const precipitationProbabilityRegEx = "Chance of precipitation is ([0-9]+?)%";
+
// initial variable declaration
const days = [];
// variables for temperature range and rain
@@ -248,7 +248,6 @@ WeatherProvider.register("weathergov", {
// variable for date
let date = "";
let weather = new WeatherObject();
- weather.precipitation = 0;
for (const forecast of forecasts) {
if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) {
@@ -263,7 +262,8 @@ WeatherProvider.register("weathergov", {
minTemp = [];
maxTemp = [];
- weather.precipitation = 0;
+ const precipitation = new RegExp(precipitationProbabilityRegEx, "g").exec(forecast.detailedForecast);
+ if (precipitation) weather.precipitationProbability = precipitation[1];
// set new date
date = moment(forecast.startTime).format("YYYY-MM-DD");
@@ -295,18 +295,6 @@ WeatherProvider.register("weathergov", {
return days.slice(1);
},
- /*
- * Unit conversions
- */
- // conversion to inches
- convertLength(meters) {
- if (this.config.units === "imperial") {
- return meters * 39.3701;
- } else {
- return meters;
- }
- },
-
/*
* Convert the icons to a more usable name.
*/
diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js
index d3d31148..effe9b44 100644
--- a/modules/default/weather/providers/yr.js
+++ b/modules/default/weather/providers/yr.js
@@ -65,7 +65,8 @@ WeatherProvider.register("yr", {
}
const forecastXHours = this.getForecastForXHoursFrom(forecast.data);
forecast.weatherType = this.convertWeatherType(forecastXHours.summary.symbol_code, forecast.time);
- forecast.precipitation = forecastXHours.details?.precipitation_amount;
+ forecast.precipitationAmount = forecastXHours.details?.precipitation_amount;
+ forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation;
forecast.minTemperature = forecastXHours.details?.air_temperature_min;
forecast.maxTemperature = forecastXHours.details?.air_temperature_max;
return this.getWeatherDataFrom(forecast, stellarData, weatherData.properties.meta.units);
@@ -358,7 +359,7 @@ WeatherProvider.register("yr", {
},
getWeatherDataFrom(forecast, stellarData, units) {
- const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh);
+ const weather = new WeatherObject();
const stellarTimesToday = stellarData?.today ? this.getStellarTimesFrom(stellarData.today, moment().format("YYYY-MM-DD")) : undefined;
const stellarTimesTomorrow = stellarData?.tomorrow ? this.getStellarTimesFrom(stellarData.tomorrow, moment().add(1, "days").format("YYYY-MM-DD")) : undefined;
@@ -370,7 +371,8 @@ WeatherProvider.register("yr", {
weather.maxTemperature = forecast.maxTemperature;
weather.weatherType = forecast.weatherType;
weather.humidity = forecast.data.instant.details.relative_humidity;
- weather.precipitation = forecast.precipitation;
+ weather.precipitationAmount = forecast.precipitationAmount;
+ weather.precipitationProbability = forecast.precipitationProbability;
weather.precipitationUnits = units.precipitation_amount;
if (stellarTimesToday) {
@@ -554,7 +556,8 @@ WeatherProvider.register("yr", {
for (const forecast of weatherData.properties.timeseries) {
forecast.symbol = forecast.data.next_1_hours?.summary?.symbol_code;
- forecast.precipitation = forecast.data.next_1_hours?.details?.precipitation_amount;
+ forecast.precipitationAmount = forecast.data.next_1_hours?.details?.precipitation_amount;
+ forecast.precipitationProbability = forecast.data.next_1_hours?.details?.probability_of_precipitation;
forecast.minTemperature = forecast.data.next_1_hours?.details?.air_temperature_min;
forecast.maxTemperature = forecast.data.next_1_hours?.details?.air_temperature_max;
forecast.weatherType = this.convertWeatherType(forecast.symbol, forecast.time);
@@ -599,7 +602,8 @@ WeatherProvider.register("yr", {
const forecastXHours = forecast.data.next_12_hours ?? forecast.data.next_6_hours ?? forecast.data.next_1_hours;
if (forecastXHours) {
forecast.symbol = forecastXHours.summary?.symbol_code;
- forecast.precipitation = forecastXHours.details?.precipitation_amount;
+ forecast.precipitationAmount = forecastXHours.details?.precipitation_amount ?? forecast.data.next_6_hours?.details?.precipitation_amount; // 6 hours is likely to have precipitation amount even if 12 hours does not
+ forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation;
forecast.minTemperature = minTemperature;
forecast.maxTemperature = maxTemperature;
diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js
index 656c4882..3bb85f43 100644
--- a/modules/default/weather/weather.js
+++ b/modules/default/weather/weather.js
@@ -26,6 +26,7 @@ Module.register("weather", {
showPeriod: true,
showPeriodUpper: false,
showPrecipitationAmount: false,
+ showPrecipitationProbability: false,
showSun: true,
showWindDirection: true,
showWindDirectionAsArrow: false,
@@ -230,7 +231,7 @@ Module.register("weather", {
this.nunjucksEnvironment().addFilter(
"unit",
- function (value, type) {
+ function (value, type, valueUnit) {
if (type === "temperature") {
value = this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits)) + "°";
if (this.config.degreeLabel) {
@@ -246,11 +247,7 @@ Module.register("weather", {
if (value === null || isNaN(value) || value === 0 || value.toFixed(2) === "0.00") {
value = "";
} else {
- if (this.config.weatherProvider === "ukmetoffice" || this.config.weatherProvider === "ukmetofficedatahub") {
- value += "%";
- } else {
- value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`;
- }
+ value = WeatherUtils.convertPrecipitationUnit(value, valueUnit, this.config.units);
}
} else if (type === "humidity") {
value += "%";
diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js
index f5ebdf5d..565061da 100644
--- a/modules/default/weather/weatherobject.js
+++ b/modules/default/weather/weatherobject.js
@@ -30,10 +30,9 @@ class WeatherObject {
this.maxTemperature = null;
this.weatherType = null;
this.humidity = null;
- this.rain = null;
- this.snow = null;
- this.precipitation = null;
+ this.precipitationAmount = null;
this.precipitationUnits = null;
+ this.precipitationProbability = null;
this.feelsLikeTemp = null;
}
diff --git a/modules/default/weather/weatherutils.js b/modules/default/weather/weatherutils.js
index a03127ab..233b0742 100644
--- a/modules/default/weather/weatherutils.js
+++ b/modules/default/weather/weatherutils.js
@@ -22,6 +22,27 @@ const WeatherUtils = {
return 12;
},
+ /**
+ * Convert a value in a given unit to a string with a converted
+ * value and a postfix matching the output unit system.
+ *
+ * @param {number} value - The value to convert.
+ * @param {string} valueUnit - The unit the values has. Default is mm.
+ * @param {string} outputUnit - The unit system (imperial/metric) the return value should have.
+ * @returns {string} - A string with tha value and a unit postfix.
+ */
+ convertPrecipitationUnit(value, valueUnit, outputUnit) {
+ if (outputUnit === "imperial") {
+ if (valueUnit && valueUnit.toLowerCase() === "cm") value = value * 0.3937007874;
+ else value = value * 0.03937007874;
+ valueUnit = "in";
+ } else {
+ valueUnit = valueUnit ? valueUnit : "mm";
+ }
+
+ return `${value.toFixed(2)} ${valueUnit}`;
+ },
+
/**
* Convert temp (from degrees C) into imperial or metric unit depending on
* your config
diff --git a/tests/configs/modules/weather/forecastweather_units.js b/tests/configs/modules/weather/forecastweather_units.js
index 7e1ac86f..22a9820a 100644
--- a/tests/configs/modules/weather/forecastweather_units.js
+++ b/tests/configs/modules/weather/forecastweather_units.js
@@ -15,7 +15,8 @@ let config = {
location: "Munich",
mockData: '"#####WEATHERDATA#####"',
weatherEndpoint: "/forecast/daily",
- decimalSymbol: "_"
+ decimalSymbol: "_",
+ showPrecipitationAmount: true
}
}
]
diff --git a/tests/configs/modules/weather/hourlyweather_showPrecipitation.js b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js
new file mode 100644
index 00000000..4ba579e1
--- /dev/null
+++ b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js
@@ -0,0 +1,27 @@
+/* MagicMirror² Test config hourly weather
+ *
+ * By rejas https://github.com/rejas
+ * MIT Licensed.
+ */
+let config = {
+ timeFormat: 12,
+
+ modules: [
+ {
+ module: "weather",
+ position: "bottom_bar",
+ config: {
+ type: "hourly",
+ location: "Berlin",
+ mockData: '"#####WEATHERDATA#####"',
+ showPrecipitationAmount: true,
+ showPrecipitationProbability: true
+ }
+ }
+ ]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {
+ module.exports = config;
+}
diff --git a/tests/e2e/modules/weather_forecast_spec.js b/tests/e2e/modules/weather_forecast_spec.js
index cd036916..99882491 100644
--- a/tests/e2e/modules/weather_forecast_spec.js
+++ b/tests/e2e/modules/weather_forecast_spec.js
@@ -81,16 +81,29 @@ describe("Weather module: Weather Forecast", () => {
});
});
- describe("Forecast weather units", () => {
+ describe("Forecast weather with imperial units", () => {
beforeAll(async () => {
await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_units.js", {});
});
- 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);
- });
- }
+ describe("Temperature units", () => {
+ 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);
+ });
+ }
+ });
+
+ describe("Precipitation units", () => {
+ const precipitations = [undefined, "0.10 in"];
+ for (const [index, precipitation] of precipitations.entries()) {
+ if (precipitation) {
+ it("should render precipitation value " + precipitation, async () => {
+ await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitationAmount`, precipitation);
+ });
+ }
+ }
+ });
});
});
diff --git a/tests/e2e/modules/weather_hourly_spec.js b/tests/e2e/modules/weather_hourly_spec.js
index 18ee6972..2c98623d 100644
--- a/tests/e2e/modules/weather_hourly_spec.js
+++ b/tests/e2e/modules/weather_hourly_spec.js
@@ -33,4 +33,32 @@ describe("Weather module: Weather Hourly Forecast", () => {
}
});
});
+
+ describe("Show precipitations", () => {
+ beforeAll(async () => {
+ await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_showPrecipitation.js", {});
+ });
+
+ describe("Shows precipitation amount", () => {
+ const amounts = [undefined, undefined, undefined, "0.13 mm", "0.13 mm"];
+ for (const [index, amount] of amounts.entries()) {
+ if (amount) {
+ it(`should render precipitation amount ${amount}`, async () => {
+ await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitationAmount`, amount);
+ });
+ }
+ }
+ });
+
+ describe("Shows precipitation propability", () => {
+ const propabilities = [undefined, undefined, "12%", "36%", "44%"];
+ for (const [index, pop] of propabilities.entries()) {
+ if (pop) {
+ it(`should render propability ${pop}`, async () => {
+ await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitationProbability`, pop);
+ });
+ }
+ }
+ });
+ });
});
diff --git a/tests/mocks/weather_forecast.json b/tests/mocks/weather_forecast.json
index 8cd5a6eb..ed062c3f 100644
--- a/tests/mocks/weather_forecast.json
+++ b/tests/mocks/weather_forecast.json
@@ -64,7 +64,9 @@
],
"speed": 2.21,
"deg": 81,
- "clouds": 100
+ "clouds": 100,
+ "pop": 0.7,
+ "rain": 2.51
},
{
"dt": 1568545200,
diff --git a/tests/unit/modules/default/weather/weather_utils_spec.js b/tests/unit/modules/default/weather/weather_utils_spec.js
new file mode 100644
index 00000000..6d26f8fa
--- /dev/null
+++ b/tests/unit/modules/default/weather/weather_utils_spec.js
@@ -0,0 +1,45 @@
+const weather = require("../../../../../modules/default/weather/weatherutils.js");
+
+describe("Weather utils tests", () => {
+ describe("convertPrecipitationUnit tests", () => {
+ it("Should keep value and unit if outputUnit is undefined", () => {
+ const values = [1, 2];
+ const units = ["mm", "cm"];
+
+ for (let i = 0; i < values.length; i++) {
+ var result = weather.convertPrecipitationUnit(values[i], units[i], undefined);
+ expect(result).toBe(`${values[i].toFixed(2)} ${units[i]}`);
+ }
+ });
+
+ it("Should keep value and unit if outputUnit is metric", () => {
+ const values = [1, 2];
+ const units = ["mm", "cm"];
+
+ for (let i = 0; i < values.length; i++) {
+ var result = weather.convertPrecipitationUnit(values[i], units[i], "metric");
+ expect(result).toBe(`${values[i].toFixed(2)} ${units[i]}`);
+ }
+ });
+
+ it("Should use mm unit if input unit is undefined", () => {
+ const values = [1, 2];
+
+ for (let i = 0; i < values.length; i++) {
+ var result = weather.convertPrecipitationUnit(values[i], undefined, "metric");
+ expect(result).toBe(`${values[i].toFixed(2)} mm`);
+ }
+ });
+
+ it("Should convert value and unit if outputUnit is imperial", () => {
+ const values = [1, 2];
+ const units = ["mm", "cm"];
+ const expectedValues = [0.04, 0.79];
+
+ for (let i = 0; i < values.length; i++) {
+ var result = weather.convertPrecipitationUnit(values[i], units[i], "imperial");
+ expect(result).toBe(`${expectedValues[i]} in`);
+ }
+ });
+ });
+});
diff --git a/translations/cs.json b/translations/cs.json
index 3c4b1f5f..50749034 100644
--- a/translations/cs.json
+++ b/translations/cs.json
@@ -26,7 +26,7 @@
"NNW": "SSZ",
"FEELS": "Pocitově {DEGREE}",
- "PRECIP": "Pravděpodobnost deště",
+ "PRECIP_POP": "Pravděpodobnost deště",
"NEWSFEED_NO_ITEMS": "Žádné zprávy.",
diff --git a/translations/da.json b/translations/da.json
index 6f52154a..3418b4e5 100644
--- a/translations/da.json
+++ b/translations/da.json
@@ -26,7 +26,7 @@
"NNW": "NNV",
"FEELS": "Føles som {DEGREE}",
- "PRECIP": "Sandsynlighed for nedbør",
+ "PRECIP_POP": "Sandsynlighed for nedbør",
"MODULE_CONFIG_CHANGED": "Konfigurationsmulighederne for {MODULE_NAME} modulet er ændret.\nSe venligst dokumentationen.",
"MODULE_CONFIG_ERROR": "Fejl i {MODULE_NAME} modulet. {ERROR}",
diff --git a/translations/de.json b/translations/de.json
index 39b9c726..8d9a761d 100644
--- a/translations/de.json
+++ b/translations/de.json
@@ -26,7 +26,8 @@
"NNW": "NNW",
"FEELS": "Gefühlt {DEGREE}",
- "PRECIP": "Niederschlagswahrscheinlichkeit",
+ "PRECIP_POP": "Niederschlagswahrscheinlichkeit",
+ "PRECIP_AMOUNT": "Niederschlagsmenge",
"MODULE_CONFIG_CHANGED": "Die Konfigurationsoptionen für das Modul „{MODULE_NAME}“ haben sich geändert. \nBitte überprüfen Sie die Dokumentation.",
"MODULE_CONFIG_ERROR": "Fehler im Modul „{MODULE_NAME}“. {ERROR}",
diff --git a/translations/en.json b/translations/en.json
index 4bb50182..f323ce24 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -25,7 +25,8 @@
"NNW": "NNW",
"FEELS": "Feels like {DEGREE}",
- "PRECIP": "PoP",
+ "PRECIP_POP": "PoP",
+ "PRECIP_AMOUNT": "Precipitation amount",
"MODULE_CONFIG_CHANGED": "The configuration options for the {MODULE_NAME} module have changed.\nPlease check the documentation.",
"MODULE_CONFIG_ERROR": "Error in the {MODULE_NAME} module. {ERROR}",
diff --git a/translations/es.json b/translations/es.json
index 5c982468..9386aca0 100644
--- a/translations/es.json
+++ b/translations/es.json
@@ -26,7 +26,7 @@
"NNW": "NNO",
"FEELS": "Sensación térmica de {DEGREE}",
- "PRECIP": "Precipitación",
+ "PRECIP_POP": "Precipitación",
"MODULE_CONFIG_CHANGED": "Las opciones de configuración para el módulo {MODULE_NAME} han cambiado. \nVerifique la documentación.",
diff --git a/translations/fi.json b/translations/fi.json
index 31e04312..748dd1d1 100644
--- a/translations/fi.json
+++ b/translations/fi.json
@@ -26,7 +26,7 @@
"NNW": "PPL",
"FEELS": "Tuntuu kuin {DEGREE}",
- "PRECIP": "Sateen todennäköisyys",
+ "PRECIP_POP": "Sateen todennäköisyys",
"UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.",
"UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}.",
diff --git a/translations/fr.json b/translations/fr.json
index be56821f..2b34e253 100644
--- a/translations/fr.json
+++ b/translations/fr.json
@@ -26,7 +26,7 @@
"NNW": "NNO",
"FEELS": "Ressenti {DEGREE}",
- "PRECIP": "Probabilité de précipitations",
+ "PRECIP_POP": "Probabilité de précipitations",
"MODULE_CONFIG_CHANGED": "Les options de configuration du module {MODULE_NAME} ont changé.\nVeuillez consulter la documentation.",
"MODULE_CONFIG_ERROR": "Erreur dans le module {MODULE_NAME}. {ERROR}",
diff --git a/translations/gl.json b/translations/gl.json
index d0ef36bd..856653df 100644
--- a/translations/gl.json
+++ b/translations/gl.json
@@ -35,5 +35,5 @@
"UPDATE_INFO_MULTIPLE": "A instalación actual está {COMMIT_COUNT} commits detrás da rama {BRANCH_NAME}.",
"FEELS": "Semella como {DEGREE}",
- "PRECIP": "Precipitacións"
+ "PRECIP_POP": "Precipitacións"
}
diff --git a/translations/gu.json b/translations/gu.json
index c9bf7e24..3e1610e0 100644
--- a/translations/gu.json
+++ b/translations/gu.json
@@ -26,7 +26,7 @@
"NNW": "ઉઉપ",
"FEELS": "{DEGREE} જેવું લાગશે",
- "PRECIP": "PoP",
+ "PRECIP_POP": "PoP",
"MODULE_CONFIG_CHANGED": "{MODULE_NAME} મોડ્યુલ માટે ગોઠવણી વિકલ્પો બદલાયા છે. \nકૃપા કરીને દસ્તાવેજોને તપાસો.",
diff --git a/translations/he.json b/translations/he.json
index e066b59f..9703b46e 100644
--- a/translations/he.json
+++ b/translations/he.json
@@ -26,7 +26,7 @@
"NNW": "צ-צ-מע",
"FEELS": "מרגיש כמו {DEGREE}",
- "PRECIP": "משקעים",
+ "PRECIP_POP": "משקעים",
"UPDATE_NOTIFICATION": "עדכון זמין ל-MagicMirror²",
"UPDATE_NOTIFICATION_MODULE": "עדכון זמין ב-{MODULE_NAME} מודול",
diff --git a/translations/hi.json b/translations/hi.json
index 8124709e..f673dce8 100644
--- a/translations/hi.json
+++ b/translations/hi.json
@@ -26,7 +26,7 @@
"NNW": "उउप",
"FEELS": "{DEGREE} की तरह लगना",
- "PRECIP": "PoP",
+ "PRECIP_POP": "PoP",
"MODULE_CONFIG_CHANGED": "{MODULE_NAME} मॉड्यूल के लिए कॉन्फ़िगरेशन विकल्प बदल गए हैं। n कृपया दस्तावेज़ देखें।",
diff --git a/translations/ko.json b/translations/ko.json
index 5361137a..ebc301ea 100644
--- a/translations/ko.json
+++ b/translations/ko.json
@@ -26,7 +26,7 @@
"NNW": "북북서풍",
"FEELS": "체감온도 {DEGREE}",
- "PRECIP": "PoP",
+ "PRECIP_POP": "PoP",
"MODULE_CONFIG_CHANGED": "모듈 {MODULE_NAME}의 설정값이 바뀌었습니다.\n매뉴얼을 참고하세요.",
"MODULE_CONFIG_ERROR": "에러 : {MODULE_NAME} - {ERROR}",
diff --git a/translations/lt.json b/translations/lt.json
index 95cbef93..354261c9 100644
--- a/translations/lt.json
+++ b/translations/lt.json
@@ -26,7 +26,7 @@
"NNW": "ŠŠV",
"FEELS": "Jutiminė temp. {DEGREE}",
- "PRECIP": "Krituliai",
+ "PRECIP_POP": "Krituliai",
"UPDATE_NOTIFICATION": "Galimas MagicMirror² naujinimas.",
"UPDATE_NOTIFICATION_MODULE": "Galimas {MODULE_NAME} naujinimas.",
diff --git a/translations/nb.json b/translations/nb.json
index cbf0f188..cd4a29f8 100644
--- a/translations/nb.json
+++ b/translations/nb.json
@@ -26,6 +26,8 @@
"NNW": "NNV",
"FEELS": "Føles som {DEGREE}",
+ "PRECIP_POP": "Sannsynlighet for nedbør",
+ "PRECIP_AMOUNT": "Nedbørsmengde",
"UPDATE_NOTIFICATION": "MagicMirror²-oppdatering er tilgjengelig.",
"UPDATE_NOTIFICATION_MODULE": "Oppdatering tilgjengelig for modulen {MODULE_NAME}.",
diff --git a/translations/nl.json b/translations/nl.json
index 3ee70785..6358d021 100644
--- a/translations/nl.json
+++ b/translations/nl.json
@@ -26,7 +26,7 @@
"NNW": "NNW",
"FEELS": "Voelt als {DEGREE}",
- "PRECIP": "Neerslagkans",
+ "PRECIP_POP": "Neerslagkans",
"MODULE_CONFIG_CHANGED": "De configuratie opties voor de module {MODULE_NAME} zijn gewijzigd.\nControleer de documentatie.",
"MODULE_CONFIG_ERROR": "Fout in de {MODULE_NAME} module. {ERROR}",
diff --git a/translations/pl.json b/translations/pl.json
index 61e24b8f..c62a3c4c 100644
--- a/translations/pl.json
+++ b/translations/pl.json
@@ -26,7 +26,7 @@
"NNW": "NNW",
"FEELS": "Odczuwalna {DEGREE}",
- "PRECIP": "Szansa opadów",
+ "PRECIP_POP": "Szansa opadów",
"UPDATE_NOTIFICATION": "Dostępna jest aktualizacja MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Dostępna jest aktualizacja modułu {MODULE_NAME}.",
diff --git a/translations/pt-br.json b/translations/pt-br.json
index 65f6a58b..315b3a45 100644
--- a/translations/pt-br.json
+++ b/translations/pt-br.json
@@ -24,7 +24,7 @@
"NNW": "NNO",
"FEELS": "Percebida {DEGREE}",
- "PRECIP": "PoP",
+ "PRECIP_POP": "PoP",
"UPDATE_NOTIFICATION": "Nova atualização para MagicMirror² disponível.",
"UPDATE_NOTIFICATION_MODULE": "Atualização para o módulo {MODULE_NAME} disponível.",
diff --git a/translations/pt.json b/translations/pt.json
index 8887dcbe..12fb27c4 100644
--- a/translations/pt.json
+++ b/translations/pt.json
@@ -26,7 +26,7 @@
"NNW": "NNO",
"FEELS": "Sentida {DEGREE}",
- "PRECIP": "Prob. Precipitação",
+ "PRECIP_POP": "Prob. Precipitação",
"MODULE_CONFIG_CHANGED": "As opções na configuração do módulo {MODULE_NAME} foram alteradas.\nPor favor, verifica a documentação.",
diff --git a/translations/tr.json b/translations/tr.json
index 5f8ca41b..8008d78b 100644
--- a/translations/tr.json
+++ b/translations/tr.json
@@ -26,7 +26,7 @@
"NNW": "KKB",
"FEELS": "Hissedilen {DEGREE}",
- "PRECIP": "Yağış",
+ "PRECIP_POP": "Yağış",
"UPDATE_NOTIFICATION": "MagicMirror² güncellemesi mevcut.",
"UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} modulü için güncelleme mevcut.",
diff --git a/translations/uk.json b/translations/uk.json
index e5050b3d..d6b7efff 100644
--- a/translations/uk.json
+++ b/translations/uk.json
@@ -26,7 +26,7 @@
"NNW": "ПнПнЗх",
"FEELS": "Відчувається як {DEGREE}",
- "PRECIP": "Опади",
+ "PRECIP_POP": "Опади",
"UPDATE_NOTIFICATION": "Є оновлення для MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Є оновлення для модуля {MODULE_NAME}.",
diff --git a/translations/zh-tw.json b/translations/zh-tw.json
index 83edc148..6000d0c9 100644
--- a/translations/zh-tw.json
+++ b/translations/zh-tw.json
@@ -26,7 +26,7 @@
"NNW": "北偏西風",
"FEELS": "體感溫度 {DEGREE}",
- "PRECIP": "降雨機率",
+ "PRECIP_POP": "降雨機率",
"MODULE_CONFIG_CHANGED": "模組 {MODULE_NAME} 的設定檔選項已更改。\n請參見說明文件。",
"MODULE_CONFIG_ERROR": "{MODULE_NAME} 模組發生錯誤。{ERROR}",