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).
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;
},