mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 11:50:00 +00:00
Allow temp and wind units to be specified separately if required.
This commit is contained in:
parent
2970568eab
commit
a619fc4fef
6
CHANGELOG.md
Normal file → Executable file
6
CHANGELOG.md
Normal file → Executable file
@ -14,10 +14,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
### Added
|
||||
Added UK Met Office Datapoint feed as a provider in the default weather module.
|
||||
- added new provider class
|
||||
- added suncalc.js dependency to calculate sun times (not provided in datapoint feed)
|
||||
- added "ukunits": temp in degrees C, wind speed in MPH, precipitation in %
|
||||
- added suncalc.js dependency to calculate sun times (not provided in UK Met Office feed)
|
||||
- added "tempUnits" and "windUnits" to allow, for example, temp in metric (i.e. celsius) and wind in imperial (i.e. mph). These will override "units" if specified, otherwise the "units" value will be used.
|
||||
- use Feels Like temp from feed if present
|
||||
- optionally display precipitation in current weather
|
||||
- optionally display probability of precipitation (PoP) in current weather (UK Met Office data)
|
||||
|
||||
### Updated
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Weather Module
|
||||
|
||||
This module is aimed to be the replacement for the current `currentweather` and `weatherforcast` modules. The module will be configurable to be used as a current weather view, or to show the forecast. This way the module can be used twice to fullfil both purposes.
|
||||
This module is aimed to be the replacement for the current `currentweather` and `weatherforcast` modules. The module will be configurable to be used as a current weather view, or to show the forecast. This way the module can be used twice to fullfil both purposes.
|
||||
|
||||
The biggest change is the use of weather providers. This way we are not bound to one API source. And users can choose which API they want to use as their source.
|
||||
|
||||
@ -37,7 +37,9 @@ The following properties can be configured:
|
||||
| ---------------------------- | -----------
|
||||
| `weatherProvider` | Which weather provider should be used. <br><br> **Possible values:** `openweathermap` , `darksky` , `weathergov` or `ukmetoffice`<br> **Default value:** `openweathermap`
|
||||
| `type` | Which type of weather data should be displayed. <br><br> **Possible values:** `current` or `forecast` <br> **Default value:** `current`
|
||||
| `units` | What units to use. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit, `ukunits` = Celsius (wind speed mph) <br> **Default value:** `config.units`
|
||||
| `units` | What units to use. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit <br> **Default value:** `config.units`
|
||||
| `tempUnits` | What units to use for temperature. If specified overrides `units` setting. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit <br> **Default value:** `units`
|
||||
| `windUnits` | What units to use for wind speed. If specified overrides `units` setting. Specified by config.js <br><br> **Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit <br> **Default value:** `units`
|
||||
| `roundTemp` | Round temperature value to nearest integer. <br><br> **Possible values:** `true` (round to integer) or `false` (display exact value with decimal point) <br> **Default value:** `false`
|
||||
| `degreeLabel` | Show the degree label for your chosen units (Metric = C, Imperial = F, Kelvin = K). <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
|
||||
| `updateInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `600000` (10 minutes)
|
||||
|
@ -18,9 +18,9 @@ This is the script in which the weather provider will be defined. In it's most s
|
||||
````javascript
|
||||
WeatherProvider.register("yourprovider", {
|
||||
providerName: "YourProvider",
|
||||
|
||||
|
||||
fetchCurrentWeather() {},
|
||||
|
||||
|
||||
fetchWeatherForecast() {}
|
||||
});
|
||||
````
|
||||
@ -91,9 +91,11 @@ A convenience function to make requests. It returns a promise.
|
||||
|
||||
| Property | Type | Value/Unit |
|
||||
| --- | --- | --- |
|
||||
| units | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` and `ukunits` |
|
||||
| units | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |
|
||||
| tempUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |
|
||||
| windUnits | `string` | Gets initialized with the constructor. <br> Possible values: `metric`, `imperial` |
|
||||
| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. |
|
||||
| windSpeed |`number` | Metric: `meter/second` <br> Imperial: `miles/hour` <br> UKunits: `miles/hour` |
|
||||
| windSpeed |`number` | Metric: `meter/second` <br> Imperial: `miles/hour` |
|
||||
| windDirection |`number` | Direction of the wind in degrees. |
|
||||
| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. |
|
||||
| sunset |`object` | [Moment.js](https://momentjs.com/) object of sunset. |
|
||||
@ -104,7 +106,7 @@ A convenience function to make requests. It returns a promise.
|
||||
| humidity | `number` | Percentage of humidity |
|
||||
| rain | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||
| snow | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||
| precipitation | `number` | Metric: `millimeters` <br> Imperial: `inches` <br> Ukunits: `percent` |
|
||||
| precipitation | `number` | Metric: `millimeters` <br> Imperial: `inches` <br> UK Met Office provider: `percent` |
|
||||
|
||||
#### Current weather
|
||||
|
||||
|
4
modules/default/weather/providers/darksky.js
Normal file → Executable file
4
modules/default/weather/providers/darksky.js
Normal file → Executable file
@ -58,7 +58,7 @@ WeatherProvider.register("darksky", {
|
||||
|
||||
// Implement WeatherDay generator.
|
||||
generateWeatherDayFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
currentWeather.date = moment();
|
||||
currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity);
|
||||
@ -76,7 +76,7 @@ WeatherProvider.register("darksky", {
|
||||
const days = [];
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
const weather = new WeatherObject(this.config.units);
|
||||
const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
weather.date = moment(forecast.time, "X");
|
||||
weather.minTemperature = forecast.temperatureMin;
|
||||
|
12
modules/default/weather/providers/openweathermap.js
Normal file → Executable file
12
modules/default/weather/providers/openweathermap.js
Normal file → Executable file
@ -68,7 +68,7 @@ WeatherProvider.register("openweathermap", {
|
||||
* Generate a WeatherObject based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
currentWeather.humidity = currentWeatherData.main.humidity;
|
||||
currentWeather.temperature = currentWeatherData.main.temp;
|
||||
@ -92,7 +92,7 @@ WeatherProvider.register("openweathermap", {
|
||||
return this.fetchForecastDaily(forecasts);
|
||||
}
|
||||
// if weatherEndpoint does not match forecast or forecast/daily, what should be returned?
|
||||
const days = [new WeatherObject(this.config.units)];
|
||||
const days = [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits)];
|
||||
return days;
|
||||
},
|
||||
|
||||
@ -109,7 +109,7 @@ WeatherProvider.register("openweathermap", {
|
||||
let snow = 0;
|
||||
// variable for date
|
||||
let date = "";
|
||||
let weather = new WeatherObject(this.config.units);
|
||||
let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
|
||||
@ -123,7 +123,7 @@ WeatherProvider.register("openweathermap", {
|
||||
// push weather information to days array
|
||||
days.push(weather);
|
||||
// create new weather-object
|
||||
weather = new WeatherObject(this.config.units);
|
||||
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
minTemp = [];
|
||||
maxTemp = [];
|
||||
@ -140,7 +140,7 @@ WeatherProvider.register("openweathermap", {
|
||||
weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) {
|
||||
weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
|
||||
}
|
||||
@ -187,7 +187,7 @@ WeatherProvider.register("openweathermap", {
|
||||
const days = [];
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
const weather = new WeatherObject(this.config.units);
|
||||
const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
weather.date = moment(forecast.dt, "X");
|
||||
weather.minTemperature = forecast.temp.min;
|
||||
|
@ -19,8 +19,7 @@ WeatherProvider.register("ukmetoffice", {
|
||||
|
||||
units: {
|
||||
imperial: "us",
|
||||
metric: "si",
|
||||
ukunits: "uk"
|
||||
metric: "si"
|
||||
},
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
@ -79,7 +78,7 @@ WeatherProvider.register("ukmetoffice", {
|
||||
* Generate a WeatherObject based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
// data times are always UTC
|
||||
let nowUtc = moment.utc()
|
||||
@ -132,7 +131,7 @@ WeatherProvider.register("ukmetoffice", {
|
||||
// loop round the (5) periods getting the data
|
||||
// for each period array, Day is [0], Night is [1]
|
||||
for (j in forecasts.SiteRep.DV.Location.Period) {
|
||||
const weather = new WeatherObject(this.config.units);
|
||||
const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
// data times are always UTC
|
||||
dateStr = forecasts.SiteRep.DV.Location.Period[j].value
|
||||
@ -212,14 +211,14 @@ WeatherProvider.register("ukmetoffice", {
|
||||
* Convert temp (from degrees C) if required
|
||||
*/
|
||||
convertTemp(tempInC) {
|
||||
return this.units === "imperial" ? tempInC * 9 / 5 + 32 : tempInC;
|
||||
return this.tempUnits === "imperial" ? tempInC * 9 / 5 + 32 : tempInC;
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert wind speed (from mph) if required
|
||||
*/
|
||||
convertWindSpeed(windInMph) {
|
||||
return this.units === "metric" ? windInMph * 2.23694 : windInMph;
|
||||
return this.windUnits === "metric" ? windInMph * 2.23694 : windInMph;
|
||||
},
|
||||
|
||||
/*
|
||||
|
10
modules/default/weather/providers/weathergov.js
Normal file → Executable file
10
modules/default/weather/providers/weathergov.js
Normal file → Executable file
@ -67,7 +67,7 @@ WeatherProvider.register("weathergov", {
|
||||
* Generate a WeatherObject based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
currentWeather.temperature = currentWeatherData.temperature;
|
||||
currentWeather.windSpeed = currentWeatherData.windSpeed.split(" ", 1);
|
||||
@ -95,7 +95,7 @@ WeatherProvider.register("weathergov", {
|
||||
let maxTemp = [];
|
||||
// variable for date
|
||||
let date = "";
|
||||
let weather = new WeatherObject(this.config.units);
|
||||
let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
weather.precipitation = 0;
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
@ -109,7 +109,7 @@ WeatherProvider.register("weathergov", {
|
||||
// push weather information to days array
|
||||
days.push(weather);
|
||||
// create new weather-object
|
||||
weather = new WeatherObject(this.config.units);
|
||||
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||
|
||||
minTemp = [];
|
||||
maxTemp = [];
|
||||
@ -134,7 +134,7 @@ WeatherProvider.register("weathergov", {
|
||||
minTemp.push(forecast.temperature);
|
||||
maxTemp.push(forecast.temperature);
|
||||
}
|
||||
|
||||
|
||||
// last day
|
||||
// calculate minimum/maximum temperature, specify rain amount
|
||||
weather.minTemperature = Math.min.apply(null, minTemp);
|
||||
@ -202,7 +202,7 @@ WeatherProvider.register("weathergov", {
|
||||
}
|
||||
|
||||
return "night-clear";
|
||||
} else if (weatherType.includes("Dust") || weatherType.includes("Sand")) {
|
||||
} else if (weatherType.includes("Dust") || weatherType.includes("Sand")) {
|
||||
return "dust";
|
||||
} else if (weatherType.includes("Fog")) {
|
||||
return "fog";
|
||||
|
@ -19,6 +19,10 @@ Module.register("weather",{
|
||||
locationID: false,
|
||||
appid: "",
|
||||
units: config.units,
|
||||
|
||||
tempUnits: config.units,
|
||||
windUnits: config.units,
|
||||
|
||||
updateInterval: 10 * 60 * 1000, // every 10 minutes
|
||||
animationSpeed: 1000,
|
||||
timeFormat: config.timeFormat,
|
||||
@ -85,6 +89,7 @@ Module.register("weather",{
|
||||
// Start the weather module.
|
||||
start: function () {
|
||||
moment.locale(this.config.lang);
|
||||
|
||||
// Initialize the weather provider.
|
||||
this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this);
|
||||
|
||||
@ -189,13 +194,13 @@ Module.register("weather",{
|
||||
|
||||
this.nunjucksEnvironment().addFilter("unit", function (value, type) {
|
||||
if (type === "temperature") {
|
||||
if (this.config.units === "metric" || this.config.units === "imperial" || this.config.units === "ukunits") {
|
||||
if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") {
|
||||
value += "°";
|
||||
}
|
||||
if (this.config.degreeLabel) {
|
||||
if (this.config.units === "metric" || this.config.units === "ukunits") {
|
||||
if (this.config.tempUnits === "metric") {
|
||||
value += "C";
|
||||
} else if (this.config.units === "imperial") {
|
||||
} else if (this.config.tempUnits === "imperial") {
|
||||
value += "F";
|
||||
} else {
|
||||
value += "K";
|
||||
|
@ -13,8 +13,11 @@
|
||||
// As soon as we start implementing the forecast, mode properties will be added.
|
||||
|
||||
class WeatherObject {
|
||||
constructor(units) {
|
||||
constructor(units, tempUnits, windUnits) {
|
||||
|
||||
this.units = units;
|
||||
this.tempUnits = tempUnits;
|
||||
this.windUnits = windUnits;
|
||||
this.date = null;
|
||||
this.windSpeed = null;
|
||||
this.windDirection = null;
|
||||
@ -69,7 +72,7 @@ class WeatherObject {
|
||||
}
|
||||
|
||||
beaufortWindSpeed() {
|
||||
const windInKmh = (this.units === "imperial" || this.units === "ukunits") ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000;
|
||||
const windInKmh = (this.windUnits === "imperial") ? this.windSpeed * 1.609344 : 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) {
|
||||
@ -87,8 +90,8 @@ class WeatherObject {
|
||||
if (this.feelsLikeTemp) {
|
||||
return this.feelsLikeTemp
|
||||
}
|
||||
const windInMph = (this.units === "imperial" || this.units === "ukunits") ? this.windSpeed : this.windSpeed * 2.23694;
|
||||
const tempInF = this.units === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
|
||||
const windInMph = (this.windUnits === "imperial") ? this.windSpeed : this.windSpeed * 2.23694;
|
||||
const tempInF = this.tempUnits === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
|
||||
let feelsLike = tempInF;
|
||||
|
||||
if (windInMph > 3 && tempInF < 50) {
|
||||
@ -102,6 +105,6 @@ class WeatherObject {
|
||||
- 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity;
|
||||
}
|
||||
|
||||
return this.units === "imperial" ? feelsLike : (feelsLike - 32) * 5 / 9;
|
||||
return this.tempUnits === "imperial" ? feelsLike : (feelsLike - 32) * 5 / 9;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user