From de04c12d3c89a89738a03aaaf2409b01e21ee2f4 Mon Sep 17 00:00:00 2001 From: fewieden Date: Sun, 30 Dec 2018 20:46:25 +0100 Subject: [PATCH 1/2] fix rain amount information for different units and providers, documentation --- modules/default/weather/forecast.njk | 2 +- modules/default/weather/providers/README.md | 129 ++++++++++++++++++ modules/default/weather/providers/darksky.js | 6 +- .../weather/providers/openweathermap.js | 6 +- modules/default/weather/weather.js | 18 +-- modules/default/weather/weatherobject.js | 1 + modules/default/weather/weatherprovider.js | 6 +- 7 files changed, 150 insertions(+), 18 deletions(-) create mode 100644 modules/default/weather/providers/README.md diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk index edc11115..1f247867 100644 --- a/modules/default/weather/forecast.njk +++ b/modules/default/weather/forecast.njk @@ -12,7 +12,7 @@ {% if config.showRainAmount %} - {{f.rain | formatRain}} + {{f.rain | unit("rain")}} {% endif %} diff --git a/modules/default/weather/providers/README.md b/modules/default/weather/providers/README.md new file mode 100644 index 00000000..f204a88a --- /dev/null +++ b/modules/default/weather/providers/README.md @@ -0,0 +1,129 @@ +# MagicMirror² Weather Module Weather Provider Development Documentation + +This document describes the way to develop your own MagicMirror² weather module weather provider. + +Table of Contents: + +- The weather provider file: yourprovider.js + - [Weather provider methods to implement](#weather-provider-methods-to-implement) + - [Weather Provider instance methods](#weather-provider-instance-methods) + - [WeatherObject](#weatherobject) + +--- + +## The weather provider file: yourprovider.js + +This is the script in which the weather provider will be defined. In it's most simple form, the weather provider must implement the following: + +````javascript +WeatherProvider.register("yourprovider", { + providerName: "YourProvider", + + fetchCurrentWeather() {}, + + fetchWeatherForecast() {} +}); +```` + +### Weather provider methods to implement + +#### `fetchCurrentWeather()` + +This method is called when the weather module tries to fetch the current weather of your provider. The implementation of this method is required. +The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. +After the response is processed, the current weather information (as a [WeatherObject](#weatherobject)) needs to be set with `this.setCurrentWeather(currentWeather);`. +It will then automatically refresh the module DOM with the new data. + +#### `fetchWeatherForecast()` + +This method is called when the weather module tries to fetch the weather weather of your provider. The implementation of this method is required. +The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. +After the response is processed, the weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setCurrentWeather(forecast);`. +It will then automatically refresh the module DOM with the new data. + +### Weather Provider instance methods + +#### `init()` + +Called when a weather provider is initialized. + +#### `setConfig(config)` + +Called to set the config, this config is the same as the weather module's config. + +#### `start()` + +Called when the weather provider is about to start. + +#### `currentWeather()` + +This returns a WeatherDay object for the current weather. + +#### `weatherForecast()` + +This returns an array of WeatherDay objects for the weather forecast. + +#### `fetchedLocation()` + +This returns the name of the fetched location or an empty string. + +#### `setCurrentWeather(currentWeatherObject)` + +Set the currentWeather and notify the delegate that new information is available. + +#### `setWeatherForecast(weatherForecastArray)` + +Set the weatherForecastArray and notify the delegate that new information is available. + +#### `setFetchedLocation(name)` + +Set the fetched location name. + +#### `updateAvailable()` + +Notify the delegate that new weather is available. + +#### `fetchData(url, method, data)` + +A convinience function to make requests. It returns a promise. + +### WeatherObject + +| Property | Type | Value/Unit | +| --- | --- | --- | +| units | `string` | Gets initialized with the constructor.
Possible values: `metric` and `imperial` | +| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. | +| windSpeed |`number` | Metric: `meter/second`
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. | +| temperature | `number` | Current temperature | +| minTemperature | `number` | Lowest temperature of the day. | +| maxTemperature | `number` | Highest temperature of the day. | +| weatherType | `string` | Icon name of the weather type.
Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) | +| humidity | `number` | Percentage of humidity | +| rain | `number` | Metric: `millimeters`
Imperial: `inches` | + +#### Current weather + +For the current weather object the following properties are required: + +- humidity +- sunrise +- sunset +- temperature +- units +- weatherType +- windDirection +- windSpeed + +#### Weather forecast + +For the forecast weather object the following properties are required: + +- date +- maxTemperature +- minTemperature +- rain +- units +- weatherType diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index e4cb78b3..4b1bc4ee 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -81,7 +81,11 @@ WeatherProvider.register("darksky", { weather.minTemperature = forecast.temperatureMin; weather.maxTemperature = forecast.temperatureMax; weather.weatherType = this.convertWeatherType(forecast.icon); - weather.rain = forecast.precipAccumulation; + if (this.config.units === "metric" && !isNaN(forecast.precipAccumulation)) { + weather.rain = forecast.precipAccumulation * 10; + } else { + weather.rain = forecast.precipAccumulation; + } days.push(weather); } diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index caa88b21..89ccfcf5 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -96,7 +96,11 @@ WeatherProvider.register("openweathermap", { weather.minTemperature = forecast.temp.min; weather.maxTemperature = forecast.temp.max; weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); - weather.rain = forecast.rain; + if (this.config.units === "imperial" && !isNaN(forecast.rain)) { + weather.rain = forecast.rain / 25.4 + } else { + weather.rain = forecast.rain; + } days.push(weather); } diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index d2a64749..eff3f90e 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -194,6 +194,12 @@ Module.register("weather",{ value += "K"; } } + } else if (type === "rain") { + if (isNaN(value)) { + value = ""; + } else { + value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`; + } } return value; @@ -202,17 +208,5 @@ Module.register("weather",{ this.nunjucksEnvironment().addFilter("roundValue", function(value) { return this.roundValue(value); }.bind(this)); - - this.nunjucksEnvironment().addFilter("formatRain", function(value) { - if (isNaN(value)) { - return ""; - } - - if(this.config.units === "imperial") { - return `${(parseFloat(value) / 25.4).toFixed(2)} in`; - } else { - return `${parseFloat(value).toFixed(1)} mm`; - } - }.bind(this)); } }); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 599708c3..8768d49d 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -25,6 +25,7 @@ class WeatherObject { this.maxTemperature = null; this.weatherType = null; this.humidity = null; + this.rain = null; } cardinalWindDirection() { diff --git a/modules/default/weather/weatherprovider.js b/modules/default/weather/weatherprovider.js index bb139991..34654453 100644 --- a/modules/default/weather/weatherprovider.js +++ b/modules/default/weather/weatherprovider.js @@ -46,7 +46,7 @@ var WeatherProvider = Class.extend({ }, // Called when the weather provider is about to start. - start: function(config) { + start: function() { Log.info(`Weather provider: ${this.providerName} started.`); }, @@ -72,7 +72,7 @@ var WeatherProvider = Class.extend({ return this.weatherForecastArray; }, - // This returns the name of the fetched location or an empty string + // This returns the name of the fetched location or an empty string. fetchedLocation: function() { return this.fetchedLocationName || ""; }, @@ -93,7 +93,7 @@ var WeatherProvider = Class.extend({ this.updateAvailable(); }, - // Set the fetched location name + // Set the fetched location name. setFetchedLocation: function(name) { this.fetchedLocationName = name; }, From 40a30c24a088154533b05a881984cea54783aeff Mon Sep 17 00:00:00 2001 From: fewieden Date: Sun, 30 Dec 2018 20:52:27 +0100 Subject: [PATCH 2/2] link provider readme in module readme --- modules/default/weather/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index ee9ec7b8..89e65de1 100644 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -92,3 +92,7 @@ The following properties can be configured: | `apiKey` | The [DarkSky](https://darksky.net/dev/register) API key, which can be obtained by creating an DarkSky account.

This value is **REQUIRED** | `lat` | The geo coordinate latitude.

This value is **REQUIRED** | `lon` | The geo coordinate longitude.

This value is **REQUIRED** + +## API Provider Development + +If you want to add another API provider checkout the [Guide](providers).