mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 19:53:36 +00:00
Merge pull request #1590 from vincep5/develop
Adding new weather provider for weather.gov
This commit is contained in:
commit
4203065a06
@ -50,6 +50,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Added fade, fadePoint and maxNumberOfDays properties to the forecast mode [#1516](https://github.com/MichMich/MagicMirror/issues/1516)
|
||||
- Fixed Loading string and decimalSymbol string replace [#1538](https://github.com/MichMich/MagicMirror/issues/1538)
|
||||
- Show Snow amounts in new weather module [#1545](https://github.com/MichMich/MagicMirror/issues/1545)
|
||||
- Added weather.gov as a new weather provider for US locations
|
||||
|
||||
## [2.6.0] - 2019-01-01
|
||||
|
||||
|
@ -35,20 +35,20 @@ The following properties can be configured:
|
||||
|
||||
| Option | Description
|
||||
| ---------------------------- | -----------
|
||||
| `weatherProvider` | Which weather provider should be used. <br><br> **Possible values:** `openweathermap` and `darksky` <br> **Default value:** `openweathermap`
|
||||
| `type` | Which type of weather data should be displayed. <br><br> **Possible values:** `current` and `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 <br> **Default value:** `config.units`
|
||||
| `weatherProvider` | Which weather provider should be used. <br><br> **Possible values:** `openweathermap` , `darksky` , or `weathergov` <br> **Default value:** `openweathermap`
|
||||
| `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 <br> **Default value:** `config.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`
|
||||
| `degreeLabel` | Show the degree label for your chosen units (Metric = C, Imperial = F, Kelvins = 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)
|
||||
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `1000` (1 second)
|
||||
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:** `0` - `5000` <br> **Default value:** `1000` (1 second)
|
||||
| `timeFormat` | Use 12 or 24 hour format. <br><br> **Possible values:** `12` or `24` <br> **Default value:** uses value of _config.timeFormat_
|
||||
| `showPeriod` | Show the period (am/pm) with 12 hour format <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
|
||||
| `showPeriodUpper` | Show the period (AM/PM) with 12 hour format as uppercase <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
|
||||
| `lang` | The language of the days. <br><br> **Possible values:** `en`, `nl`, `ru`, etc ... <br> **Default value:** uses value of _config.language_
|
||||
| `decimalSymbol` | The decimal symbol to use.<br><br> **Possible values:** `.`, `,` or any other symbol.<br> **Default value:** `.`
|
||||
| `initialLoadDelay` | The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds) <br><br> **Possible values:** `1000` - `5000` <br> **Default value:** `0`
|
||||
| `appendLocationNameToHeader` | If set to `true`, the returned location name will be appended to the header of the module, if the header is enabled. This is mainly intresting when using calender based weather. <br><br> **Default value:** `true`
|
||||
| `appendLocationNameToHeader` | If set to `true`, the returned location name will be appended to the header of the module, if the header is enabled. This is mainly interesting when using calender based weather. <br><br> **Default value:** `true`
|
||||
| `calendarClass` | The class for the calender module to base the event based weather information on. <br><br> **Default value:** `'calendar'`
|
||||
|
||||
#### Current weather options
|
||||
@ -62,7 +62,7 @@ The following properties can be configured:
|
||||
| `showHumidity` | Show the current humidity <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
|
||||
| `showIndoorTemperature` | If you have another module that emits the `INDOOR_TEMPERATURE` notification, the indoor temperature will be displayed <br> **Default value:** `false`
|
||||
| `showIndoorHumidity` | If you have another module that emits the `INDOOR_HUMIDITY` notification, the indoor humidity will be displayed <br> **Default value:** `false`
|
||||
| `showFeelsLike` | Shows the Feels like temperature weather. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `true`
|
||||
| `showFeelsLike` | Shows the Feels like temperature weather. <br><br> **Possible values:** `true` or `false`<br>**Default value:** `true`
|
||||
|
||||
#### Weather forecast options
|
||||
|
||||
@ -96,6 +96,15 @@ The following properties can be configured:
|
||||
| `lat` | The geo coordinate latitude. <br><br> This value is **REQUIRED**
|
||||
| `lon` | The geo coordinate longitude. <br><br> This value is **REQUIRED**
|
||||
|
||||
### Weather.gov options
|
||||
|
||||
| Option | Description
|
||||
| ---------------------------- | -----------
|
||||
| `apiBase` | The weather.gov base URL. <br><br> **Possible value:** `'https://api.weather.gov/points/'` <br> This value is **REQUIRED**
|
||||
| `weatherEndpoint` | The weather.gov API endPoint. <br><br> **Possible values:** `/forecast` for forecast and `/forecast/hourly` for current. <br> This value is **REQUIRED**
|
||||
| `lat` | The geo coordinate latitude. <br><br> This value is **REQUIRED**
|
||||
| `lon` | The geo coordinate longitude. <br><br> This value is **REQUIRED**
|
||||
|
||||
## API Provider Development
|
||||
|
||||
If you want to add another API provider checkout the [Guide](providers).
|
||||
|
@ -85,7 +85,7 @@ Notify the delegate that new weather is available.
|
||||
|
||||
#### `fetchData(url, method, data)`
|
||||
|
||||
A convinience function to make requests. It returns a promise.
|
||||
A convenience function to make requests. It returns a promise.
|
||||
|
||||
### WeatherObject
|
||||
|
||||
|
@ -103,13 +103,13 @@ WeatherProvider.register("openweathermap", {
|
||||
// initial variable declaration
|
||||
const days = [];
|
||||
// variables for temperature range and rain
|
||||
var minTemp = [];
|
||||
var maxTemp = [];
|
||||
var rain = 0;
|
||||
var snow = 0;
|
||||
let minTemp = [];
|
||||
let maxTemp = [];
|
||||
let rain = 0;
|
||||
let snow = 0;
|
||||
// variable for date
|
||||
let date = "";
|
||||
var weather = new WeatherObject(this.config.units);
|
||||
let weather = new WeatherObject(this.config.units);
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
|
||||
|
256
modules/default/weather/providers/weathergov.js
Normal file
256
modules/default/weather/providers/weathergov.js
Normal file
@ -0,0 +1,256 @@
|
||||
/* global WeatherProvider, WeatherObject */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
* Provider: weather.gov
|
||||
*
|
||||
* By Vince Peri
|
||||
* MIT Licensed.
|
||||
*
|
||||
* This class is a provider for weather.gov.
|
||||
* Note that this is only for US locations (lat and lon) and does not require an API key
|
||||
* Since it is free, there are some items missing - like sunrise, sunset, humidity, etc.
|
||||
*/
|
||||
|
||||
WeatherProvider.register("weathergov", {
|
||||
|
||||
// Set the name of the provider.
|
||||
// This isn't strictly necessary, since it will fallback to the provider identifier
|
||||
// But for debugging (and future alerts) it would be nice to have the real name.
|
||||
providerName: "Weather.gov",
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchCurrentWeather() {
|
||||
this.fetchData(this.getUrl())
|
||||
.then(data => {
|
||||
if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
|
||||
// Did not receive usable new data.
|
||||
// Maybe this needs a better check?
|
||||
return;
|
||||
}
|
||||
|
||||
const currentWeather = this.generateWeatherObjectFromCurrentWeather(data.properties.periods[0]);
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function(request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
})
|
||||
},
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchWeatherForecast() {
|
||||
this.fetchData(this.getUrl())
|
||||
.then(data => {
|
||||
if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
|
||||
// Did not receive usable new data.
|
||||
// Maybe this needs a better check?
|
||||
return;
|
||||
}
|
||||
|
||||
const forecast = this.generateWeatherObjectsFromForecast(data.properties.periods);
|
||||
this.setWeatherForecast(forecast);
|
||||
})
|
||||
.catch(function(request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
})
|
||||
},
|
||||
|
||||
/** Weather.gov Specific Methods - These are not part of the default provider methods */
|
||||
/*
|
||||
* Gets the complete url for the request
|
||||
*/
|
||||
getUrl() {
|
||||
return this.config.apiBase + this.config.lat + "," + this.config.lon + this.config.weatherEndpoint;
|
||||
},
|
||||
|
||||
/*
|
||||
* Generate a WeatherObject based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherObjectFromCurrentWeather(currentWeatherData) {
|
||||
const currentWeather = new WeatherObject(this.config.units);
|
||||
|
||||
currentWeather.temperature = currentWeatherData.temperature;
|
||||
currentWeather.windSpeed = currentWeatherData.windSpeed.split(" ", 1);
|
||||
currentWeather.windDirection = this.convertDirectiontoDegrees(currentWeatherData.windDirection);
|
||||
currentWeather.weatherType = this.convertWeatherType(currentWeatherData.shortForecast, currentWeatherData.isDaytime);
|
||||
|
||||
return currentWeather;
|
||||
},
|
||||
|
||||
/*
|
||||
* Generate WeatherObjects based on forecast information
|
||||
*/
|
||||
generateWeatherObjectsFromForecast(forecasts) {
|
||||
return this.fetchForecastDaily(forecasts);
|
||||
},
|
||||
|
||||
/*
|
||||
* fetch forecast information for daily forecast.
|
||||
*/
|
||||
fetchForecastDaily(forecasts) {
|
||||
// initial variable declaration
|
||||
const days = [];
|
||||
// variables for temperature range and rain
|
||||
let minTemp = [];
|
||||
let maxTemp = [];
|
||||
// variable for date
|
||||
let date = "";
|
||||
let weather = new WeatherObject(this.config.units);
|
||||
weather.precipitation = 0;
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
|
||||
if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) {
|
||||
|
||||
// calculate minimum/maximum temperature, specify rain amount
|
||||
weather.minTemperature = Math.min.apply(null, minTemp);
|
||||
weather.maxTemperature = Math.max.apply(null, maxTemp);
|
||||
|
||||
// push weather information to days array
|
||||
days.push(weather);
|
||||
// create new weather-object
|
||||
weather = new WeatherObject(this.config.units);
|
||||
|
||||
minTemp = [];
|
||||
maxTemp = [];
|
||||
weather.precipitation = 0;
|
||||
|
||||
// set new date
|
||||
date = moment(forecast.startTime).format("YYYY-MM-DD");
|
||||
|
||||
// specify date
|
||||
weather.date = moment(forecast.startTime);
|
||||
|
||||
// If the first value of today is later than 17:00, we have an icon at least!
|
||||
weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime);
|
||||
}
|
||||
|
||||
if (moment(forecast.startTime).format("H") >= 8 && moment(forecast.startTime).format("H") <= 17) {
|
||||
weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime);
|
||||
}
|
||||
|
||||
// the same day as before
|
||||
// add values from forecast to corresponding variables
|
||||
minTemp.push(forecast.temperature);
|
||||
maxTemp.push(forecast.temperature);
|
||||
}
|
||||
|
||||
// last day
|
||||
// calculate minimum/maximum temperature, specify rain amount
|
||||
weather.minTemperature = Math.min.apply(null, minTemp);
|
||||
weather.maxTemperature = Math.max.apply(null, maxTemp);
|
||||
|
||||
// push weather information to days array
|
||||
days.push(weather);
|
||||
return days.slice(1);
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert the icons to a more usable name.
|
||||
*/
|
||||
convertWeatherType(weatherType, isDaytime) {
|
||||
//https://w1.weather.gov/xml/current_obs/weather.php
|
||||
// There are way too many types to create, so lets just look for certain strings
|
||||
|
||||
if (weatherType.includes("Cloudy") || weatherType.includes("Partly")) {
|
||||
if (isDaytime) {
|
||||
return "day-cloudy";
|
||||
}
|
||||
|
||||
return "night-cloudy";
|
||||
} else if (weatherType.includes("Overcast")) {
|
||||
if (isDaytime) {
|
||||
return "cloudy";
|
||||
}
|
||||
|
||||
return "night-cloudy";
|
||||
} else if (weatherType.includes("Freezing") || weatherType.includes("Ice")) {
|
||||
return "rain-mix";
|
||||
} else if (weatherType.includes("Snow")) {
|
||||
if (isDaytime) {
|
||||
return "snow";
|
||||
}
|
||||
|
||||
return "night-snow";
|
||||
} else if (weatherType.includes("Thunderstorm")) {
|
||||
if (isDaytime) {
|
||||
return "thunderstorm";
|
||||
}
|
||||
|
||||
return "night-thunderstorm";
|
||||
} else if (weatherType.includes("Showers")) {
|
||||
if (isDaytime) {
|
||||
return "showers";
|
||||
}
|
||||
|
||||
return "night-showers";
|
||||
} else if (weatherType.includes("Rain") || weatherType.includes("Drizzle")) {
|
||||
if (isDaytime) {
|
||||
return "rain";
|
||||
}
|
||||
|
||||
return "night-rain";
|
||||
} else if (weatherType.includes("Breezy") || weatherType.includes("Windy")) {
|
||||
if (isDaytime) {
|
||||
return "cloudy-windy";
|
||||
}
|
||||
|
||||
return "night-alt-cloudy-windy";
|
||||
} else if (weatherType.includes("Fair") || weatherType.includes("Clear") || weatherType.includes("Few") || weatherType.includes("Sunny")) {
|
||||
if (isDaytime) {
|
||||
return "day-sunny";
|
||||
}
|
||||
|
||||
return "night-clear";
|
||||
} else if (weatherType.includes("Dust") || weatherType.includes("Sand")) {
|
||||
return "dust";
|
||||
} else if (weatherType.includes("Fog")) {
|
||||
return "fog";
|
||||
} else if (weatherType.includes("Smoke")) {
|
||||
return "smoke";
|
||||
} else if (weatherType.includes("Haze")) {
|
||||
return "day-haze";
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
Convert the direction into Degrees
|
||||
*/
|
||||
convertDirectiontoDegrees(direction) {
|
||||
if (direction === "NNE"){
|
||||
return 33.75;
|
||||
} else if (direction === "NE") {
|
||||
return 56.25;
|
||||
} else if (direction === "ENE") {
|
||||
return 78.75;
|
||||
} else if (direction === "E") {
|
||||
return 101.25;
|
||||
} else if (direction === "ESE") {
|
||||
return 123.75;
|
||||
} else if (direction === "SE") {
|
||||
return 146.25;
|
||||
} else if (direction === "SSE") {
|
||||
return 168.75;
|
||||
} else if (direction === "S") {
|
||||
return 191.25;
|
||||
} else if (direction === "SSW") {
|
||||
return 213.75;
|
||||
} else if (direction === "SW") {
|
||||
return 236.25;
|
||||
} else if (direction === "WSW") {
|
||||
return 258.75;
|
||||
} else if (direction === "W") {
|
||||
return 281.25;
|
||||
} else if (direction === "WNW") {
|
||||
return 303.75;
|
||||
} else if (direction === "NW") {
|
||||
return 326.25;
|
||||
} else if (direction === "NNW") {
|
||||
return 348.75;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user