mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 11:50:00 +00:00
A first setup of the new Weather Module
This commit is contained in:
parent
8a101f9e9a
commit
ef172592b8
@ -16,7 +16,8 @@ var defaultModules = [
|
||||
"helloworld",
|
||||
"newsfeed",
|
||||
"weatherforecast",
|
||||
"updatenotification"
|
||||
"updatenotification",
|
||||
"weather"
|
||||
];
|
||||
|
||||
/*************** DO NOT EDIT THE LINE BELOW ***************/
|
||||
|
120
modules/default/weather/providers/openweathermap.js
Normal file
120
modules/default/weather/providers/openweathermap.js
Normal file
@ -0,0 +1,120 @@
|
||||
/* global WeatherProvider, WeatherDay */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
*
|
||||
* By Michael Teeuw http://michaelteeuw.nl
|
||||
* MIT Licensed.
|
||||
*
|
||||
* This class is the blueprint for a weather provider.
|
||||
*/
|
||||
|
||||
WeatherProvider.register("openweathermap", {
|
||||
|
||||
// Set the name of the provider.
|
||||
// This isn't strictly nessecery, since it will fallback to the provider identifier
|
||||
// But for debugging (and future alerts) it would be nice to have the real name.
|
||||
providerName: "OpenWeatherMap",
|
||||
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchCurrentWeather: function() {
|
||||
var apiVersion = "2.5"
|
||||
var apiBase = "http://api.openweathermap.org/data/"
|
||||
var weatherEndpoint = "weather"
|
||||
|
||||
var url = apiBase + apiVersion + "/" + weatherEndpoint + this.getParams()
|
||||
|
||||
this.fetchData(url)
|
||||
.then(data => {
|
||||
Log.log(data)
|
||||
|
||||
if (!data || !data.main || typeof data.main.temp === "undefined") {
|
||||
// Did not receive usable new data.
|
||||
// Maybe this needs a better check?
|
||||
return;
|
||||
}
|
||||
|
||||
var currentWeather = this.generateWeatherDayFromCurrentWeather(data)
|
||||
this.setCurrentWeather(currentWeather)
|
||||
})
|
||||
.catch(function(request) {
|
||||
Log.error("Could not load data ... ", request)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
/** OpenWeatherMap Specific Methods - These are not part of the default provider methods */
|
||||
|
||||
|
||||
/*
|
||||
* Generate a WeatherDay based on currentWeatherInformation
|
||||
*/
|
||||
generateWeatherDayFromCurrentWeather: function(currentWeatherData) {
|
||||
var currentWeather = new WeatherDay()
|
||||
|
||||
currentWeather.humidity = parseFloat(currentWeatherData.main.humidity)
|
||||
currentWeather.temperature = parseFloat(currentWeatherData.main.temp)
|
||||
currentWeather.windSpeed = parseFloat(currentWeatherData.wind.speed)
|
||||
currentWeather.windDirection = currentWeatherData.wind.deg
|
||||
currentWeather.weatherType = this.convertWeatherType(currentWeatherData.weather[0].icon)
|
||||
currentWeather.sunrise = new Date(currentWeatherData.sys.sunrise * 1000)
|
||||
currentWeather.sunset = new Date(currentWeatherData.sys.sunset * 1000)
|
||||
|
||||
return currentWeather
|
||||
},
|
||||
|
||||
/*
|
||||
* Convert the OpenWeatherMap icons to a more usable name.
|
||||
*/
|
||||
convertWeatherType: function(weatherType) {
|
||||
var weatherTypes = {
|
||||
"01d": "day-sunny",
|
||||
"02d": "day-cloudy",
|
||||
"03d": "cloudy",
|
||||
"04d": "cloudy-windy",
|
||||
"09d": "showers",
|
||||
"10d": "rain",
|
||||
"11d": "thunderstorm",
|
||||
"13d": "snow",
|
||||
"50d": "fog",
|
||||
"01n": "night-clear",
|
||||
"02n": "night-cloudy",
|
||||
"03n": "night-cloudy",
|
||||
"04n": "night-cloudy",
|
||||
"09n": "night-showers",
|
||||
"10n": "night-rain",
|
||||
"11n": "night-thunderstorm",
|
||||
"13n": "night-snow",
|
||||
"50n": "night-alt-cloudy-windy"
|
||||
}
|
||||
|
||||
return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null
|
||||
},
|
||||
|
||||
/* getParams(compliments)
|
||||
* Generates an url with api parameters based on the config.
|
||||
*
|
||||
* return String - URL params.
|
||||
*/
|
||||
getParams: function() {
|
||||
var params = "?";
|
||||
if(this.config.locationID) {
|
||||
params += "id=" + this.config.locationID;
|
||||
} else if(this.config.location) {
|
||||
params += "q=" + this.config.location;
|
||||
} else if (this.firstEvent && this.firstEvent.geo) {
|
||||
params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon
|
||||
} else if (this.firstEvent && this.firstEvent.location) {
|
||||
params += "q=" + this.firstEvent.location;
|
||||
} else {
|
||||
this.hide(this.config.animationSpeed, {lockString:this.identifier});
|
||||
return;
|
||||
}
|
||||
|
||||
params += "&units=" + this.config.units;
|
||||
params += "&lang=" + this.config.lang;
|
||||
params += "&APPID=" + this.config.apiKey;
|
||||
|
||||
return params;
|
||||
},
|
||||
});
|
62
modules/default/weather/weather.js
Normal file
62
modules/default/weather/weather.js
Normal file
@ -0,0 +1,62 @@
|
||||
/* global Module, WeatherProvider */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
*
|
||||
* By Michael Teeuw http://michaelteeuw.nl
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
Module.register("weather",{
|
||||
|
||||
// Default module config.
|
||||
defaults: {
|
||||
foo: "bar",
|
||||
weatherProvider: "openweathermap"
|
||||
},
|
||||
|
||||
// Module properties.
|
||||
weatherProvider: null,
|
||||
|
||||
// Return the scripts that are nessecery for the weather module.
|
||||
getScripts: function () {
|
||||
var scripts = [
|
||||
"weatherprovider.js",
|
||||
"weatherday.js"
|
||||
];
|
||||
|
||||
// Add the provider file to the required scripts.
|
||||
scripts.push(this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js"))
|
||||
|
||||
return scripts
|
||||
},
|
||||
|
||||
// Start the weather module.
|
||||
start: function () {
|
||||
// Initialize the weather provider.
|
||||
this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this)
|
||||
|
||||
// Let the weather provider know we are starting.
|
||||
this.weatherProvider.start()
|
||||
|
||||
// Fetch the current weather. This is something we need to schedule.
|
||||
this.weatherProvider.fetchCurrentWeather()
|
||||
},
|
||||
|
||||
// Generate the dom. This is now pretty simple for debugging.
|
||||
getDom: function() {
|
||||
var wrapper = document.createElement("div")
|
||||
|
||||
wrapper.innerHTML += "Name: " + this.weatherProvider.providerName + "<br>"
|
||||
wrapper.innerHTML += JSON.stringify(this.weatherProvider.currentWeather())
|
||||
|
||||
return wrapper
|
||||
},
|
||||
|
||||
// What to do when the weather provider has new information available?
|
||||
updateAvailable: function() {
|
||||
Log.log("New weather information available.")
|
||||
console.info(this.weatherProvider.currentWeather())
|
||||
this.updateDom(0);
|
||||
}
|
||||
});
|
24
modules/default/weather/weatherday.js
Normal file
24
modules/default/weather/weatherday.js
Normal file
@ -0,0 +1,24 @@
|
||||
/* global Class */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
*
|
||||
* By Michael Teeuw http://michaelteeuw.nl
|
||||
* MIT Licensed.
|
||||
*
|
||||
* This class is the blueprint for a day which includes weather information.
|
||||
*/
|
||||
|
||||
// Currently this is focused on the information which is nessecery for the current weather.
|
||||
// As soon as we start implementing the forecast, mode properties will be added.
|
||||
|
||||
class WeatherDay {
|
||||
constructor() {
|
||||
this.windSpeed = null
|
||||
this.windDirection = null
|
||||
this.sunrise = null
|
||||
this.sunset = null
|
||||
this.temperature = null
|
||||
this.weatherType = null
|
||||
}
|
||||
};
|
135
modules/default/weather/weatherprovider.js
Normal file
135
modules/default/weather/weatherprovider.js
Normal file
@ -0,0 +1,135 @@
|
||||
/* global Class */
|
||||
|
||||
/* Magic Mirror
|
||||
* Module: Weather
|
||||
*
|
||||
* By Michael Teeuw http://michaelteeuw.nl
|
||||
* MIT Licensed.
|
||||
*
|
||||
* This class is the blueprint for a weather provider.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base BluePrint for the WeatherProvider
|
||||
*/
|
||||
var WeatherProvider = Class.extend({
|
||||
// Weather Provider Properties
|
||||
providerName: null,
|
||||
|
||||
// The following properties have accestor methods.
|
||||
// Try to not access them directly.
|
||||
currentWeatherDay: null,
|
||||
weatherForecastArray: null,
|
||||
|
||||
// The following properties will be set automaticly.
|
||||
// You do not need to overwrite these properties.
|
||||
config: null,
|
||||
delegate: null,
|
||||
providerIdentifier: null,
|
||||
|
||||
|
||||
// Weather Provider Methods
|
||||
// All the following methods can be overwrited, although most are good as they are.
|
||||
|
||||
// Called when a weather provider is initialized.
|
||||
init: function(config) {
|
||||
this.config = config;
|
||||
Log.info("Weather provider: " + this.providerName + " initialized.")
|
||||
},
|
||||
|
||||
// Called to set the config, this config is the same as the weather module's config.
|
||||
setConfig: function(config) {
|
||||
this.config = config
|
||||
Log.info("Weather provider: " + this.providerName + " config set.", this.config)
|
||||
},
|
||||
|
||||
// Called when the weather provider is about to start.
|
||||
start: function(config) {
|
||||
Log.info("Weather provider: " + this.providerName + " started.")
|
||||
},
|
||||
|
||||
// This method should start the API request to fetch the current weather.
|
||||
// This method should definetly be overwritten in the provider.
|
||||
fetchCurrentWeather: function() {
|
||||
Log.warn("Weather provider: " + this.providerName + " does not subclass the fetchCurrentWeather method.")
|
||||
},
|
||||
|
||||
// This method should start the API request to fetch the weather forecast.
|
||||
// This method should definetly be overwritten in the provider.
|
||||
fetchWeatherForeCast: function() {
|
||||
Log.warn("Weather provider: " + this.providerName + " does not subclass the fetchWeatherForeCast method.")
|
||||
},
|
||||
|
||||
// This returns a WeatherDay object for the current weather.
|
||||
currentWeather: function() {
|
||||
return this.currentWeatherDay
|
||||
},
|
||||
|
||||
// This returns an array of WeatherDay objects for the weather forecast.
|
||||
weatherForecast: function() {
|
||||
return this.weatherForecastArray
|
||||
},
|
||||
|
||||
// Set the currentWeather and notify the delegate that new information is availabe.
|
||||
setCurrentWeather: function(currentWeatherDay) {
|
||||
// We should check here if we are passing a WeatherDay
|
||||
this.currentWeatherDay = currentWeatherDay
|
||||
|
||||
this.updateAvailable()
|
||||
},
|
||||
|
||||
// Notify the delegate that new weather is available.
|
||||
updateAvailable: function() {
|
||||
this.delegate.updateAvailable(this)
|
||||
},
|
||||
|
||||
// A convinience function to make requests. It returns a promise.
|
||||
fetchData: function(url, method = "GET", data = null) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open(method, url, true);
|
||||
request.onreadystatechange = function() {
|
||||
if (this.readyState === 4) {
|
||||
if (this.status === 200) {
|
||||
resolve(JSON.parse(this.response));
|
||||
} else {
|
||||
reject(request)
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Collection of registered weather providers.
|
||||
*/
|
||||
WeatherProvider.providers = []
|
||||
|
||||
/**
|
||||
* Static method to register a new weather provider.
|
||||
*/
|
||||
WeatherProvider.register = function(providerIdentifier, providerDetails) {
|
||||
WeatherProvider.providers[providerIdentifier.toLowerCase()] = WeatherProvider.extend(providerDetails)
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to initialize a new weather provider.
|
||||
*/
|
||||
WeatherProvider.initialize = function(providerIdentifier, delegate) {
|
||||
providerIdentifier = providerIdentifier.toLowerCase()
|
||||
|
||||
var provider = new WeatherProvider.providers[providerIdentifier]()
|
||||
|
||||
provider.delegate = delegate
|
||||
provider.setConfig(delegate.config)
|
||||
|
||||
provider.providerIdentifier = providerIdentifier;
|
||||
if (!provider.providerName) {
|
||||
provider.providerName = providerIdentifier
|
||||
}
|
||||
|
||||
return provider;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user