mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 19:53:36 +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
|
||||||
Added UK Met Office Datapoint feed as a provider in the default weather module.
|
Added UK Met Office Datapoint feed as a provider in the default weather module.
|
||||||
- added new provider class
|
- added new provider class
|
||||||
- added suncalc.js dependency to calculate sun times (not provided in datapoint feed)
|
- added suncalc.js dependency to calculate sun times (not provided in UK Met Office feed)
|
||||||
- added "ukunits": temp in degrees C, wind speed in MPH, precipitation in %
|
- 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
|
- 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
|
### Updated
|
||||||
|
|
||||||
|
@ -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`
|
| `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`
|
| `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`
|
| `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`
|
| `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)
|
| `updateInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `600000` (10 minutes)
|
||||||
|
@ -91,9 +91,11 @@ A convenience function to make requests. It returns a promise.
|
|||||||
|
|
||||||
| Property | Type | Value/Unit |
|
| 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. |
|
| 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. |
|
| windDirection |`number` | Direction of the wind in degrees. |
|
||||||
| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. |
|
| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. |
|
||||||
| sunset |`object` | [Moment.js](https://momentjs.com/) object of sunset. |
|
| 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 |
|
| humidity | `number` | Percentage of humidity |
|
||||||
| rain | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
| rain | `number` | Metric: `millimeters` <br> Imperial: `inches` |
|
||||||
| snow | `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
|
#### 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.
|
// Implement WeatherDay generator.
|
||||||
generateWeatherDayFromCurrentWeather(currentWeatherData) {
|
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.date = moment();
|
||||||
currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity);
|
currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity);
|
||||||
@ -76,7 +76,7 @@ WeatherProvider.register("darksky", {
|
|||||||
const days = [];
|
const days = [];
|
||||||
|
|
||||||
for (const forecast of forecasts) {
|
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.date = moment(forecast.time, "X");
|
||||||
weather.minTemperature = forecast.temperatureMin;
|
weather.minTemperature = forecast.temperatureMin;
|
||||||
|
10
modules/default/weather/providers/openweathermap.js
Normal file → Executable file
10
modules/default/weather/providers/openweathermap.js
Normal file → Executable file
@ -68,7 +68,7 @@ WeatherProvider.register("openweathermap", {
|
|||||||
* Generate a WeatherObject based on currentWeatherInformation
|
* Generate a WeatherObject based on currentWeatherInformation
|
||||||
*/
|
*/
|
||||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
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.humidity = currentWeatherData.main.humidity;
|
||||||
currentWeather.temperature = currentWeatherData.main.temp;
|
currentWeather.temperature = currentWeatherData.main.temp;
|
||||||
@ -92,7 +92,7 @@ WeatherProvider.register("openweathermap", {
|
|||||||
return this.fetchForecastDaily(forecasts);
|
return this.fetchForecastDaily(forecasts);
|
||||||
}
|
}
|
||||||
// if weatherEndpoint does not match forecast or forecast/daily, what should be returned?
|
// 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;
|
return days;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ WeatherProvider.register("openweathermap", {
|
|||||||
let snow = 0;
|
let snow = 0;
|
||||||
// variable for date
|
// variable for date
|
||||||
let 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) {
|
for (const forecast of forecasts) {
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ WeatherProvider.register("openweathermap", {
|
|||||||
// push weather information to days array
|
// push weather information to days array
|
||||||
days.push(weather);
|
days.push(weather);
|
||||||
// create new weather-object
|
// create new weather-object
|
||||||
weather = new WeatherObject(this.config.units);
|
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||||
|
|
||||||
minTemp = [];
|
minTemp = [];
|
||||||
maxTemp = [];
|
maxTemp = [];
|
||||||
@ -187,7 +187,7 @@ WeatherProvider.register("openweathermap", {
|
|||||||
const days = [];
|
const days = [];
|
||||||
|
|
||||||
for (const forecast of forecasts) {
|
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.date = moment(forecast.dt, "X");
|
||||||
weather.minTemperature = forecast.temp.min;
|
weather.minTemperature = forecast.temp.min;
|
||||||
|
@ -19,8 +19,7 @@ WeatherProvider.register("ukmetoffice", {
|
|||||||
|
|
||||||
units: {
|
units: {
|
||||||
imperial: "us",
|
imperial: "us",
|
||||||
metric: "si",
|
metric: "si"
|
||||||
ukunits: "uk"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Overwrite the fetchCurrentWeather method.
|
// Overwrite the fetchCurrentWeather method.
|
||||||
@ -79,7 +78,7 @@ WeatherProvider.register("ukmetoffice", {
|
|||||||
* Generate a WeatherObject based on currentWeatherInformation
|
* Generate a WeatherObject based on currentWeatherInformation
|
||||||
*/
|
*/
|
||||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
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
|
// data times are always UTC
|
||||||
let nowUtc = moment.utc()
|
let nowUtc = moment.utc()
|
||||||
@ -132,7 +131,7 @@ WeatherProvider.register("ukmetoffice", {
|
|||||||
// loop round the (5) periods getting the data
|
// loop round the (5) periods getting the data
|
||||||
// for each period array, Day is [0], Night is [1]
|
// for each period array, Day is [0], Night is [1]
|
||||||
for (j in forecasts.SiteRep.DV.Location.Period) {
|
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
|
// data times are always UTC
|
||||||
dateStr = forecasts.SiteRep.DV.Location.Period[j].value
|
dateStr = forecasts.SiteRep.DV.Location.Period[j].value
|
||||||
@ -212,14 +211,14 @@ WeatherProvider.register("ukmetoffice", {
|
|||||||
* Convert temp (from degrees C) if required
|
* Convert temp (from degrees C) if required
|
||||||
*/
|
*/
|
||||||
convertTemp(tempInC) {
|
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
|
* Convert wind speed (from mph) if required
|
||||||
*/
|
*/
|
||||||
convertWindSpeed(windInMph) {
|
convertWindSpeed(windInMph) {
|
||||||
return this.units === "metric" ? windInMph * 2.23694 : windInMph;
|
return this.windUnits === "metric" ? windInMph * 2.23694 : windInMph;
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
6
modules/default/weather/providers/weathergov.js
Normal file → Executable file
6
modules/default/weather/providers/weathergov.js
Normal file → Executable file
@ -67,7 +67,7 @@ WeatherProvider.register("weathergov", {
|
|||||||
* Generate a WeatherObject based on currentWeatherInformation
|
* Generate a WeatherObject based on currentWeatherInformation
|
||||||
*/
|
*/
|
||||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
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.temperature = currentWeatherData.temperature;
|
||||||
currentWeather.windSpeed = currentWeatherData.windSpeed.split(" ", 1);
|
currentWeather.windSpeed = currentWeatherData.windSpeed.split(" ", 1);
|
||||||
@ -95,7 +95,7 @@ WeatherProvider.register("weathergov", {
|
|||||||
let maxTemp = [];
|
let maxTemp = [];
|
||||||
// variable for date
|
// variable for date
|
||||||
let 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;
|
weather.precipitation = 0;
|
||||||
|
|
||||||
for (const forecast of forecasts) {
|
for (const forecast of forecasts) {
|
||||||
@ -109,7 +109,7 @@ WeatherProvider.register("weathergov", {
|
|||||||
// push weather information to days array
|
// push weather information to days array
|
||||||
days.push(weather);
|
days.push(weather);
|
||||||
// create new weather-object
|
// create new weather-object
|
||||||
weather = new WeatherObject(this.config.units);
|
weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
|
||||||
|
|
||||||
minTemp = [];
|
minTemp = [];
|
||||||
maxTemp = [];
|
maxTemp = [];
|
||||||
|
@ -19,6 +19,10 @@ Module.register("weather",{
|
|||||||
locationID: false,
|
locationID: false,
|
||||||
appid: "",
|
appid: "",
|
||||||
units: config.units,
|
units: config.units,
|
||||||
|
|
||||||
|
tempUnits: config.units,
|
||||||
|
windUnits: config.units,
|
||||||
|
|
||||||
updateInterval: 10 * 60 * 1000, // every 10 minutes
|
updateInterval: 10 * 60 * 1000, // every 10 minutes
|
||||||
animationSpeed: 1000,
|
animationSpeed: 1000,
|
||||||
timeFormat: config.timeFormat,
|
timeFormat: config.timeFormat,
|
||||||
@ -85,6 +89,7 @@ Module.register("weather",{
|
|||||||
// Start the weather module.
|
// Start the weather module.
|
||||||
start: function () {
|
start: function () {
|
||||||
moment.locale(this.config.lang);
|
moment.locale(this.config.lang);
|
||||||
|
|
||||||
// Initialize the weather provider.
|
// Initialize the weather provider.
|
||||||
this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this);
|
this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this);
|
||||||
|
|
||||||
@ -189,13 +194,13 @@ Module.register("weather",{
|
|||||||
|
|
||||||
this.nunjucksEnvironment().addFilter("unit", function (value, type) {
|
this.nunjucksEnvironment().addFilter("unit", function (value, type) {
|
||||||
if (type === "temperature") {
|
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 += "°";
|
value += "°";
|
||||||
}
|
}
|
||||||
if (this.config.degreeLabel) {
|
if (this.config.degreeLabel) {
|
||||||
if (this.config.units === "metric" || this.config.units === "ukunits") {
|
if (this.config.tempUnits === "metric") {
|
||||||
value += "C";
|
value += "C";
|
||||||
} else if (this.config.units === "imperial") {
|
} else if (this.config.tempUnits === "imperial") {
|
||||||
value += "F";
|
value += "F";
|
||||||
} else {
|
} else {
|
||||||
value += "K";
|
value += "K";
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
// As soon as we start implementing the forecast, mode properties will be added.
|
// As soon as we start implementing the forecast, mode properties will be added.
|
||||||
|
|
||||||
class WeatherObject {
|
class WeatherObject {
|
||||||
constructor(units) {
|
constructor(units, tempUnits, windUnits) {
|
||||||
|
|
||||||
this.units = units;
|
this.units = units;
|
||||||
|
this.tempUnits = tempUnits;
|
||||||
|
this.windUnits = windUnits;
|
||||||
this.date = null;
|
this.date = null;
|
||||||
this.windSpeed = null;
|
this.windSpeed = null;
|
||||||
this.windDirection = null;
|
this.windDirection = null;
|
||||||
@ -69,7 +72,7 @@ class WeatherObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beaufortWindSpeed() {
|
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];
|
const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
|
||||||
for (const [index, speed] of speeds.entries()) {
|
for (const [index, speed] of speeds.entries()) {
|
||||||
if (speed > windInKmh) {
|
if (speed > windInKmh) {
|
||||||
@ -87,8 +90,8 @@ class WeatherObject {
|
|||||||
if (this.feelsLikeTemp) {
|
if (this.feelsLikeTemp) {
|
||||||
return this.feelsLikeTemp
|
return this.feelsLikeTemp
|
||||||
}
|
}
|
||||||
const windInMph = (this.units === "imperial" || this.units === "ukunits") ? this.windSpeed : this.windSpeed * 2.23694;
|
const windInMph = (this.windUnits === "imperial") ? this.windSpeed : this.windSpeed * 2.23694;
|
||||||
const tempInF = this.units === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
|
const tempInF = this.tempUnits === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
|
||||||
let feelsLike = tempInF;
|
let feelsLike = tempInF;
|
||||||
|
|
||||||
if (windInMph > 3 && tempInF < 50) {
|
if (windInMph > 3 && tempInF < 50) {
|
||||||
@ -102,6 +105,6 @@ class WeatherObject {
|
|||||||
- 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity;
|
- 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