Possibility to use the the calendar feed as the source for the weather.

This commit is contained in:
Michael Teeuw 2016-10-14 17:42:07 +02:00
parent 5858e862d9
commit 84dc1fa151
7 changed files with 162 additions and 40 deletions

View File

@ -17,7 +17,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Module API: Add Visibility locking to module system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#visibility-locking) for more information. - Module API: Add Visibility locking to module system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#visibility-locking) for more information.
- Module API: Method to overwrite the module's header. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#getheader) for more information. - Module API: Method to overwrite the module's header. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#getheader) for more information.
- Module API: Option to define the minimumn MagicMirror version to run a module. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#requiresversion) for more information. - Module API: Option to define the minimumn MagicMirror version to run a module. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#requiresversion) for more information.
- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/master/modules/default/calendar) for more information. - Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information.
- Possibility to use the the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information.
### Updated ### Updated
- Modified translations for Frysk. - Modified translations for Frysk.

View File

@ -179,7 +179,7 @@ var MM = (function() {
// set lockString if set in options. // set lockString if set in options.
if (options.lockString) { if (options.lockString) {
Log.log("Has lockstring: " + options.lockString); // Log.log("Has lockstring: " + options.lockString);
if (module.lockStrings.indexOf(options.lockString) === -1) { if (module.lockStrings.indexOf(options.lockString) === -1) {
module.lockStrings.push(options.lockString); module.lockStrings.push(options.lockString);
} }

View File

@ -337,8 +337,6 @@ var Module = Class.extend({
self.suspend(); self.suspend();
callback(); callback();
}, options); }, options);
Log.log(options);
}, },
/* showModule(module, speed, callback) /* showModule(module, speed, callback)

View File

@ -35,19 +35,20 @@ The following properties can be configured:
</tr> </tr>
<thead> <thead>
<tbody> <tbody>
<tr> <tr>
<td><code>location</code></td> <td><code>location</code></td>
<td>The location used for weather information.<br> <td>The location used for weather information.<br>
<br><b>Example:</b> <code>Amsterdam,Netherlands</code> <br><b>Example:</b> <code>'Amsterdam,Netherlands'</code>
<br><b>Default value:</b> <code>New York</code> <br><b>Default value:</b> <code>New York</code><br><br>
<strong>Note:</strong> When the <code>location</code> and <code>locationID</code> are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>locationID</code></td> <td><code>locationID</code></td>
<td>Location ID from <a href="http://bulk.openweather.org/sample/">OpenWeather</a> <b>This will override anything you put in location.</b><br>Leave blank if you want to use location. <td>Location ID from <a href="http://bulk.openweather.org/sample/">OpenWeather</a> <b>This will override anything you put in location.</b><br>Leave blank if you want to use location.
<br><b>Example:</b> <code>1234567</code> <br><b>Example:</b> <code>1234567</code>
<br><b>Default value:</b> <code></code> <br><b>Default value:</b> <code></code><br><br>
<strong>Note:</strong> When the <code>location</code> and <code>locationID</code> are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
</td> </td>
</tr> </tr>
<tr> <tr>
@ -158,6 +159,18 @@ The following properties can be configured:
<br><b>Default value:</b> <code>'weather'</code> <br><b>Default value:</b> <code>'weather'</code>
</td> </td>
</tr> </tr>
<tr>
<td><code>appendLocationNameToHeader</code></td>
<td>If set to <code>true</code>, 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><b>Default value:</b> <code>true</code>
</td>
</tr>
<tr>
<td><code>calendarClass</code></td>
<td>The class for the calender module to base the event based weather information on.<br>
<br><b>Default value:</b> <code>'calendar'</code>
</td>
</tr>
<tr> <tr>
<td><code>iconTable</code></td> <td><code>iconTable</code></td>
<td>The conversion table to convert the weather conditions to weather-icons.<br> <td>The conversion table to convert the weather conditions to weather-icons.<br>

View File

@ -11,8 +11,8 @@ Module.register("currentweather",{
// Default module config. // Default module config.
defaults: { defaults: {
location: "", location: false,
locationID: "", locationID: false,
appid: "", appid: "",
units: config.units, units: config.units,
updateInterval: 10 * 60 * 1000, // every 10 minutes updateInterval: 10 * 60 * 1000, // every 10 minutes
@ -32,6 +32,9 @@ Module.register("currentweather",{
apiBase: "http://api.openweathermap.org/data/", apiBase: "http://api.openweathermap.org/data/",
weatherEndpoint: "weather", weatherEndpoint: "weather",
appendLocationNameToHeader: true,
calendarClass: "calendar",
iconTable: { iconTable: {
"01d": "wi-day-sunny", "01d": "wi-day-sunny",
"02d": "wi-day-cloudy", "02d": "wi-day-cloudy",
@ -54,6 +57,12 @@ Module.register("currentweather",{
}, },
}, },
// create a variable for the first upcoming calendaar event. Used if no location is specified.
firstEvent: false,
// create a variable to hold the location name based on the API result.
fetchedLocatioName: "",
// Define required scripts. // Define required scripts.
getScripts: function() { getScripts: function() {
return ["moment.js"]; return ["moment.js"];
@ -103,12 +112,6 @@ Module.register("currentweather",{
return wrapper; return wrapper;
} }
if (this.config.location === "") {
wrapper.innerHTML = "Please set the openweather <i>location</i> in the config for module: " + this.name + ".";
wrapper.className = "dimmed light small";
return wrapper;
}
if (!this.loaded) { if (!this.loaded) {
wrapper.innerHTML = this.translate('LOADING'); wrapper.innerHTML = this.translate('LOADING');
wrapper.className = "dimmed light small"; wrapper.className = "dimmed light small";
@ -178,11 +181,50 @@ Module.register("currentweather",{
return wrapper; return wrapper;
}, },
// Override getHeader method.
getHeader: function() {
if (this.config.appendLocationNameToHeader) {
return this.data.header + " " + this.fetchedLocatioName;
}
return this.data.header;
},
// Override notification handler.
notificationReceived: function(notification, payload, sender) {
if (notification === "DOM_OBJECTS_CREATED") {
if (this.config.appendLocationNameToHeader) {
this.hide(0, {lockString: this.identifier});
}
}
if (notification === "CALENDAR_EVENTS") {
var senderClasses = sender.data.classes.toLowerCase().split(" ");
if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) {
var lastEvent = this.firstEvent;
this.firstEvent = false;
for (e in payload) {
var event = payload[e];
if (event.location || event.geo) {
this.firstEvent = event;
//Log.log("First upcoming event with location: ", event);
break;
}
}
}
}
},
/* updateWeather(compliments) /* updateWeather(compliments)
* Requests new data from openweather.org. * Requests new data from openweather.org.
* Calls processWeather on succesfull response. * Calls processWeather on succesfull response.
*/ */
updateWeather: function() { updateWeather: function() {
if (this.config.appid === "") {
Log.error("CurrentWeather: APPID not set!");
return;
}
var url = this.config.apiBase + this.config.apiVersion + "/" + this.config.weatherEndpoint + this.getParams(); var url = this.config.apiBase + this.config.apiVersion + "/" + this.config.weatherEndpoint + this.getParams();
var self = this; var self = this;
var retry = true; var retry = true;
@ -194,11 +236,10 @@ Module.register("currentweather",{
if (this.status === 200) { if (this.status === 200) {
self.processWeather(JSON.parse(this.response)); self.processWeather(JSON.parse(this.response));
} else if (this.status === 401) { } else if (this.status === 401) {
self.config.appid = "";
self.updateDom(self.config.animationSpeed); self.updateDom(self.config.animationSpeed);
Log.error(self.name + ": Incorrect APPID."); Log.error(self.name + ": Incorrect APPID.");
retry = false; retry = true;
} else { } else {
Log.error(self.name + ": Could not load weather."); Log.error(self.name + ": Could not load weather.");
} }
@ -218,11 +259,19 @@ Module.register("currentweather",{
*/ */
getParams: function() { getParams: function() {
var params = "?"; var params = "?";
if(this.config.locationID !== "") { if(this.config.locationID !== false) {
params += "id=" + this.config.locationID; params += "id=" + this.config.locationID;
} else { } else if(this.config.location !== false) {
params += "q=" + 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 += "&units=" + this.config.units;
params += "&lang=" + this.config.lang; params += "&lang=" + this.config.lang;
params += "&APPID=" + this.config.appid; params += "&APPID=" + this.config.appid;
@ -285,7 +334,7 @@ Module.register("currentweather",{
this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise"; this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise";
this.show(this.config.animationSpeed, {lockString:this.identifier});
this.loaded = true; this.loaded = true;
this.updateDom(this.config.animationSpeed); this.updateDom(this.config.animationSpeed);
}, },

View File

@ -35,19 +35,20 @@ The following properties can be configured:
</tr> </tr>
<thead> <thead>
<tbody> <tbody>
<tr> <tr>
<td><code>location</code></td> <td><code>location</code></td>
<td>The location used for weather information.<br> <td>The location used for weather information.<br>
<br><b>Example:</b> <code>Amsterdam,Netherlands</code> <br><b>Example:</b> <code>'Amsterdam,Netherlands'</code>
<br><b>Default value:</b> <code>New York</code> <br><b>Default value:</b> <code>New York</code><br><br>
<strong>Note:</strong> When the <code>location</code> and <code>locationID</code> are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>locationID</code></td> <td><code>locationID</code></td>
<td>Location ID from <a href="http://bulk.openweather.org/sample/">OpenWeather</a> <b>This will override anything you put in location.</b><br>Leave blank if you want to use location. <td>Location ID from <a href="http://bulk.openweather.org/sample/">OpenWeather</a> <b>This will override anything you put in location.</b><br>Leave blank if you want to use location.
<br><b>Example:</b> <code>1234567</code> <br><b>Example:</b> <code>1234567</code>
<br><b>Default value:</b> <code></code> <br><b>Default value:</b> <code></code><br><br>
<strong>Note:</strong> When the <code>location</code> and <code>locationID</code> are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
</td> </td>
</tr> </tr>
<tr> <tr>
@ -85,7 +86,6 @@ The following properties can be configured:
<br><b>Default value:</b> <code>2000</code> (2 seconds) <br><b>Default value:</b> <code>2000</code> (2 seconds)
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>lang</code></td> <td><code>lang</code></td>
<td>The language of the days.<br> <td>The language of the days.<br>
@ -139,6 +139,18 @@ The following properties can be configured:
<br><b>Default value:</b> <code>'forecast/daily'</code> <br><b>Default value:</b> <code>'forecast/daily'</code>
</td> </td>
</tr> </tr>
<tr>
<td><code>appendLocationNameToHeader</code></td>
<td>If set to <code>true</code>, 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><b>Default value:</b> <code>true</code>
</td>
</tr>
<tr>
<td><code>calendarClass</code></td>
<td>The class for the calender module to base the event based weather information on.<br>
<br><b>Default value:</b> <code>'calendar'</code>
</td>
</tr>
<tr> <tr>
<td><code>iconTable</code></td> <td><code>iconTable</code></td>
<td>The conversion table to convert the weather conditions to weather-icons.<br> <td>The conversion table to convert the weather conditions to weather-icons.<br>
@ -164,6 +176,5 @@ The following properties can be configured:
}</code> }</code>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -11,8 +11,8 @@ Module.register("weatherforecast",{
// Default module config. // Default module config.
defaults: { defaults: {
location: "", location: false,
locationID: "", locationID: false,
appid: "", appid: "",
units: config.units, units: config.units,
maxNumberOfDays: 7, maxNumberOfDays: 7,
@ -30,6 +30,9 @@ Module.register("weatherforecast",{
apiBase: "http://api.openweathermap.org/data/", apiBase: "http://api.openweathermap.org/data/",
forecastEndpoint: "forecast/daily", forecastEndpoint: "forecast/daily",
appendLocationNameToHeader: true,
calendarClass: "calendar",
iconTable: { iconTable: {
"01d": "wi-day-sunny", "01d": "wi-day-sunny",
"02d": "wi-day-cloudy", "02d": "wi-day-cloudy",
@ -52,6 +55,12 @@ Module.register("weatherforecast",{
}, },
}, },
// create a variable for the first upcoming calendaar event. Used if no location is specified.
firstEvent: false,
// create a variable to hold the location name based on the API result.
fetchedLocatioName: "",
// Define required scripts. // Define required scripts.
getScripts: function() { getScripts: function() {
return ["moment.js"]; return ["moment.js"];
@ -95,12 +104,6 @@ Module.register("weatherforecast",{
return wrapper; return wrapper;
} }
if (this.config.location === "") {
wrapper.innerHTML = "Please set the openweather <i>location</i> in the config for module: " + this.name + ".";
wrapper.className = "dimmed light small";
return wrapper;
}
if (!this.loaded) { if (!this.loaded) {
wrapper.innerHTML = this.translate("LOADING"); wrapper.innerHTML = this.translate("LOADING");
wrapper.className = "dimmed light small"; wrapper.className = "dimmed light small";
@ -156,11 +159,50 @@ Module.register("weatherforecast",{
return table; return table;
}, },
// Override getHeader method.
getHeader: function() {
if (this.config.appendLocationNameToHeader) {
return this.data.header + " " + this.fetchedLocatioName;
}
return this.data.header;
},
// Override notification handler.
notificationReceived: function(notification, payload, sender) {
if (notification === "DOM_OBJECTS_CREATED") {
if (this.config.appendLocationNameToHeader) {
this.hide(0, {lockString: this.identifier});
}
}
if (notification === "CALENDAR_EVENTS") {
var senderClasses = sender.data.classes.toLowerCase().split(" ");
if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) {
var lastEvent = this.firstEvent;
this.firstEvent = false;
for (e in payload) {
var event = payload[e];
if (event.location || event.geo) {
this.firstEvent = event;
//Log.log("First upcoming event with location: ", event);
break;
}
}
}
}
},
/* updateWeather(compliments) /* updateWeather(compliments)
* Requests new data from openweather.org. * Requests new data from openweather.org.
* Calls processWeather on succesfull response. * Calls processWeather on succesfull response.
*/ */
updateWeather: function() { updateWeather: function() {
if (this.config.appid === "") {
Log.error("WeatherForecast: APPID not set!");
return;
}
var url = this.config.apiBase + this.config.apiVersion + "/" + this.config.forecastEndpoint + this.getParams(); var url = this.config.apiBase + this.config.apiVersion + "/" + this.config.forecastEndpoint + this.getParams();
var self = this; var self = this;
var retry = true; var retry = true;
@ -172,11 +214,10 @@ Module.register("weatherforecast",{
if (this.status === 200) { if (this.status === 200) {
self.processWeather(JSON.parse(this.response)); self.processWeather(JSON.parse(this.response));
} else if (this.status === 401) { } else if (this.status === 401) {
self.config.appid = "";
self.updateDom(self.config.animationSpeed); self.updateDom(self.config.animationSpeed);
Log.error(self.name + ": Incorrect APPID."); Log.error(self.name + ": Incorrect APPID.");
retry = false; retry = true;
} else { } else {
Log.error(self.name + ": Could not load weather."); Log.error(self.name + ": Could not load weather.");
} }
@ -196,11 +237,19 @@ Module.register("weatherforecast",{
*/ */
getParams: function() { getParams: function() {
var params = "?"; var params = "?";
if(this.config.locationID !== "") { if(this.config.locationID !== false) {
params += "id=" + this.config.locationID; params += "id=" + this.config.locationID;
} else { } else if(this.config.location !== false) {
params += "q=" + 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 += "&units=" + this.config.units;
params += "&lang=" + this.config.lang; params += "&lang=" + this.config.lang;
/* /*
@ -220,6 +269,7 @@ Module.register("weatherforecast",{
* argument data object - Weather information received form openweather.org. * argument data object - Weather information received form openweather.org.
*/ */
processWeather: function(data) { processWeather: function(data) {
this.fetchedLocatioName = data.city.name + ", " + data.city.country;
this.forecast = []; this.forecast = [];
for (var i = 0, count = data.list.length; i < count; i++) { for (var i = 0, count = data.list.length; i < count; i++) {
@ -236,7 +286,7 @@ Module.register("weatherforecast",{
} }
//Log.log(this.forecast); //Log.log(this.forecast);
this.show(this.config.animationSpeed, {lockString:this.identifier});
this.loaded = true; this.loaded = true;
this.updateDom(this.config.animationSpeed); this.updateDom(this.config.animationSpeed);
}, },