From 221b6325f62a99922c2f9b3ac410299423ae1668 Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 4 Sep 2021 12:25:43 +0200 Subject: [PATCH 1/4] Cleanup some docs in the weather modules --- modules/default/weather/providers/darksky.js | 6 +- .../weather/providers/openweathermap.js | 4 +- modules/default/weather/providers/smhi.js | 62 +++++++++---------- .../weather/providers/ukmetofficedatahub.js | 5 +- .../default/weather/providers/weatherbit.js | 3 +- modules/default/weather/weatherobject.js | 4 +- 6 files changed, 44 insertions(+), 40 deletions(-) diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index ea073887..451ac98b 100755 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -8,7 +8,8 @@ * MIT Licensed * * This class is a provider for Dark Sky. - * Note that the Dark Sky API does not provide rainfall. Instead it provides snowfall and precipitation probability + * Note that the Dark Sky API does not provide rainfall. Instead it provides + * snowfall and precipitation probability */ WeatherProvider.register("darksky", { // Set the name of the provider. @@ -98,7 +99,8 @@ WeatherProvider.register("darksky", { weather.snow = 0; // The API will return centimeters if units is 'si' and will return inches for 'us' - // Note that the Dark Sky API does not provide rainfall. Instead it provides snowfall and precipitation probability + // Note that the Dark Sky API does not provide rainfall. + // Instead it provides snowfall and precipitation probability if (forecast.hasOwnProperty("precipAccumulation")) { if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) { weather.snow = forecast.precipAccumulation; diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index ec17904a..d6779d8d 100755 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -18,10 +18,10 @@ WeatherProvider.register("openweathermap", { defaults: { apiVersion: "2.5", apiBase: "https://api.openweathermap.org/data/", - weatherEndpoint: "", + weatherEndpoint: "", // can be "onecall", "forecast" or "weather" (for current) locationID: false, location: false, - lat: 0, + lat: 0, // the onecall endpoint needs lat / lon values, it doesn'T support the locationId lon: 0, apiKey: "" }, diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index 83af249b..603aa814 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -7,9 +7,8 @@ * By BuXXi https://github.com/buxxi * MIT Licensed * - * This class is a provider for SMHI (Sweden only). - * Note that SMHI doesn't provide sunrise and sundown, use SunCalc to calculate it. - * Metric system is the only supported unit. + * This class is a provider for SMHI (Sweden only). Metric system is the only + * supported unit. */ WeatherProvider.register("smhi", { providerName: "SMHI", @@ -193,7 +192,8 @@ WeatherProvider.register("smhi", { }, /** - * Resolve coordinates from the response data (probably preferably to use this if it's not matching the config values exactly) + * Resolve coordinates from the response data (probably preferably to use + * this if it's not matching the config values exactly) * * @param {object} data Response data from the weather service * @returns {{lon, lat}} the lat/long coordinates of the data @@ -237,12 +237,12 @@ WeatherProvider.register("smhi", { }, /** - * Map the icon value from SHMI to an icon that MagicMirror understands. + * Map the icon value from SMHI to an icon that MagicMirror understands. * Uses different icons depending if its daytime or nighttime. - * SHMI's description of what the numeric value means is the comment after the case. + * SMHI's description of what the numeric value means is the comment after the case. * - * @param {number} input The smhi icon value - * @param {boolean} isDayTime True if the icon should be for daytime, false for nightime + * @param {number} input The SMHI icon value + * @param {boolean} isDayTime True if the icon should be for daytime, false for nighttime * @returns {string} The icon name for the MagicMirror */ convertWeatherType(input, isDayTime) { @@ -250,57 +250,57 @@ WeatherProvider.register("smhi", { case 1: return isDayTime ? "day-sunny" : "night-clear"; // Clear sky case 2: - return isDayTime ? "day-sunny-overcast" : "night-partly-cloudy"; //Nearly clear sky + return isDayTime ? "day-sunny-overcast" : "night-partly-cloudy"; // Nearly clear sky case 3: - return isDayTime ? "day-cloudy" : "night-cloudy"; //Variable cloudiness + return isDayTime ? "day-cloudy" : "night-cloudy"; // Variable cloudiness case 4: - return isDayTime ? "day-cloudy" : "night-cloudy"; //Halfclear sky + return isDayTime ? "day-cloudy" : "night-cloudy"; // Halfclear sky case 5: - return "cloudy"; //Cloudy sky + return "cloudy"; // Cloudy sky case 6: - return "cloudy"; //Overcast + return "cloudy"; // Overcast case 7: - return "fog"; //Fog + return "fog"; // Fog case 8: - return "showers"; //Light rain showers + return "showers"; // Light rain showers case 9: - return "showers"; //Moderate rain showers + return "showers"; // Moderate rain showers case 10: - return "showers"; //Heavy rain showers + return "showers"; // Heavy rain showers case 11: - return "thunderstorm"; //Thunderstorm + return "thunderstorm"; // Thunderstorm case 12: - return "sleet"; //Light sleet showers + return "sleet"; // Light sleet showers case 13: - return "sleet"; //Moderate sleet showers + return "sleet"; // Moderate sleet showers case 14: - return "sleet"; //Heavy sleet showers + return "sleet"; // Heavy sleet showers case 15: - return "snow"; //Light snow showers + return "snow"; // Light snow showers case 16: - return "snow"; //Moderate snow showers + return "snow"; // Moderate snow showers case 17: - return "snow"; //Heavy snow showers + return "snow"; // Heavy snow showers case 18: - return "rain"; //Light rain + return "rain"; // Light rain case 19: - return "rain"; //Moderate rain + return "rain"; // Moderate rain case 20: - return "rain"; //Heavy rain + return "rain"; // Heavy rain case 21: - return "thunderstorm"; //Thunder + return "thunderstorm"; // Thunder case 22: return "sleet"; // Light sleet case 23: - return "sleet"; //Moderate sleet + return "sleet"; // Moderate sleet case 24: return "sleet"; // Heavy sleet case 25: return "snow"; // Light snowfall case 26: - return "snow"; //Moderate snowfall + return "snow"; // Moderate snowfall case 27: - return "snow"; //Heavy snowfall + return "snow"; // Heavy snowfall default: return ""; } diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 9603841b..bab1220d 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -13,9 +13,8 @@ * Hourly data for next 2 days ("hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-hourly.pdf * 3-hourly data for the next 7 days ("3hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-3-hourly.pdf * Daily data for the next 7 days ("daily") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-daily.pdf - */ - -/* NOTES + * + * NOTES * This provider requires longitude/latitude coordinates, rather than a location ID (as with the previous Met Office provider) * Provide the following in your config.js file: * weatherProvider: "ukmetofficedatahub", diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 94b9caea..17f27812 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -7,7 +7,8 @@ * By Andrew Pometti * MIT Licensed * - * This class is a provider for Weatherbit, based on Nicholas Hubbard's class for Dark Sky & Vince Peri's class for Weather.gov. + * This class is a provider for Weatherbit, based on Nicholas Hubbard's class + * for Dark Sky & Vince Peri's class for Weather.gov. */ WeatherProvider.register("weatherbit", { // Set the name of the provider. diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 9224208a..4501f681 100755 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -133,7 +133,9 @@ class WeatherObject { } /** - * Update the sunrise / sunset time depending on the location + * Update the sunrise / sunset time depending on the location. This can be + * used if your provider doesnt provide that data by itself. Then SunCalc + * is used here to calculate them according to the location. * * @param {number} lat latitude * @param {number} lon longitude From 0bf3ff9c171e7a4db6695d2907b516d5efa07458 Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 4 Sep 2021 22:49:40 +0200 Subject: [PATCH 2/4] Refer to new docs page for development documentation --- modules/default/weather/providers/README.md | 149 +------------------- 1 file changed, 2 insertions(+), 147 deletions(-) diff --git a/modules/default/weather/providers/README.md b/modules/default/weather/providers/README.md index f6e5d732..faa60a05 100755 --- a/modules/default/weather/providers/README.md +++ b/modules/default/weather/providers/README.md @@ -1,148 +1,3 @@ -# MagicMirror² Weather Module Weather Provider Development Documentation +# 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 its 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 for current weather support. -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 of your provider. The implementation of this method is required for forecast support. -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.setWeatherForecast(forecast);`. -It will then automatically refresh the module DOM with the new data. - -#### `fetchWeatherHourly()` - -This method is called when the weather module tries to fetch the weather of your provider. The implementation of this method is required for hourly support. -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 hourly weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setWeatherHourly(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. - -#### `weatherHourly()` - -This returns an array of WeatherDay objects for the hourly 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. - -#### `setWeatherHourly(weatherHourlyArray)` - -Set the weatherHourlyArray 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 convenience function to make requests. It returns a promise. - -### WeatherObject - -| Property | Type | Value/Unit | -| -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | -| units | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| tempUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| windUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `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` | -| snow | `number` | Metric: `millimeters`
Imperial: `inches` | -| precipitation | `number` | Metric: `millimeters`
Imperial: `inches`
UK Met Office provider: `percent` | - -#### 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 +For how to develop your own weather provider, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/development/weather-provider.html). From badce5146a443a990ff158a1dac55fa17d794e34 Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 4 Sep 2021 22:54:58 +0200 Subject: [PATCH 3/4] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c00f61..fc1a5c18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -438,6 +438,7 @@ Special thanks to @sdetweil for all his great contributions! - Update `ical.js` to solve various calendar issues. - Update weather city list url [#1676](https://github.com/MichMich/MagicMirror/issues/1676) - Only update clock once per minute when seconds aren't shown +- Update weatherprovider documentation. ### Fixed From 087a4727657449be8cfaf348cf1dc22d2c8d8261 Mon Sep 17 00:00:00 2001 From: rejas Date: Mon, 6 Sep 2021 21:15:23 +0200 Subject: [PATCH 4/4] Fix tomezone test error as reported by @khassel --- tests/unit/functions/weather_object_spec.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/unit/functions/weather_object_spec.js b/tests/unit/functions/weather_object_spec.js index 8878f377..c8c0faa6 100644 --- a/tests/unit/functions/weather_object_spec.js +++ b/tests/unit/functions/weather_object_spec.js @@ -1,12 +1,15 @@ const WeatherObject = require("../../../modules/default/weather/weatherobject.js"); -global.moment = require("moment"); +global.moment = require("moment-timezone"); global.SunCalc = require("suncalc"); describe("WeatherObject", function () { + let originalTimeZone; let weatherobject; beforeAll(function () { + originalTimeZone = moment.tz.guess(); + moment.tz.setDefault("Africa/Dar_es_Salaam"); weatherobject = new WeatherObject("metric", "metric", "metric", true); }); @@ -21,4 +24,8 @@ describe("WeatherObject", function () { weatherobject.updateSunTime(-6.774877582342688, 37.63345667023327); expect(weatherobject.isDayTime()).toBe(false); }); + + afterAll(function () { + moment.tz.setDefault(originalTimeZone); + }); });