Merge pull request #2650 from rejas/weather

This commit is contained in:
Michael Teeuw 2021-09-09 20:30:37 +02:00 committed by GitHub
commit 6529eaaf9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 188 deletions

View File

@ -439,6 +439,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

View File

@ -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. <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` |
| 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. <br> Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) |
| 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> 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).

View File

@ -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;

View File

@ -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: ""
},

View File

@ -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 "";
}

View File

@ -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",

View File

@ -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.

View File

@ -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

View File

@ -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);
});
});