Merge pull request #21 from MichMich/v2-beta

Update from Master
This commit is contained in:
Paul-Vincent Roll 2016-05-02 16:50:05 +02:00
commit e5f4446c82
19 changed files with 184 additions and 77 deletions

View File

@ -4,5 +4,6 @@
"validateQuoteMarks": "\"", "validateQuoteMarks": "\"",
"maximumLineLength": 250, "maximumLineLength": 250,
"requireCurlyBraces": [], "requireCurlyBraces": [],
"requireCamelCaseOrUpperCaseIdentifiers": false "requireCamelCaseOrUpperCaseIdentifiers": false,
"excludeFiles": [".jscsrc"],
} }

View File

@ -25,7 +25,7 @@ MagicMirror² focuses on a modular plugin system and uses [Electron](http://elec
## Usage ## Usage
#### Raspberry Pi Support #### Raspberry Pi Support
Electron, the app wrapper around MagicMirror², only supports the Raspberry Pi 2 & 3. The Raspberry Pi 1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself. Note the only Jessie is currently supported. If you want to use Wheezy, check out [this issue](https://github.com/MichMich/MagicMirror/issues/188). Electron, the app wrapper around MagicMirror², only supports the Raspberry Pi 2 & 3. The Raspberry Pi 1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself.
#### Automatic Installer (Raspberry Pi Only!) #### Automatic Installer (Raspberry Pi Only!)
@ -39,7 +39,7 @@ curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/v2-beta/installe
1. Download and install the latest Node.js version. 1. Download and install the latest Node.js version.
2. Clone the repository and check out the beta branch: `git clone -b v2-beta https://github.com/MichMich/MagicMirror` 2. Clone the repository and check out the beta branch: `git clone -b v2-beta https://github.com/MichMich/MagicMirror`
3. Enter the repository: `cd ~/MagicMirror` 3. Enter the repository: `cd ~/MagicMirror`
4. Install and run the app: `npm install && npm start` (You may have to restart your terminal before this works!) 4. Install and run the app: `npm install && npm start`
**Important:** `npm start` does **not** work via SSH, use `DISPLAY=:0 nohup npm start &` instead. This starts the mirror on the remote display. **Important:** `npm start` does **not** work via SSH, use `DISPLAY=:0 nohup npm start &` instead. This starts the mirror on the remote display.
@ -77,6 +77,7 @@ The following properties can be configured:
| `port` | The port on which the MagicMirror² server will run on. The default value is `8080`. | | `port` | The port on which the MagicMirror² server will run on. The default value is `8080`. |
| `language` | The language of the interface. (Note: Not all elements will be localized.) Possible values are `en`, `nl`, `ru`, `fr`, etc., but the default value is `en`. | | `language` | The language of the interface. (Note: Not all elements will be localized.) Possible values are `en`, `nl`, `ru`, `fr`, etc., but the default value is `en`. |
| `timeFormat` | The form of time notation that will be used. Possible values are `12` or `24`. The default is `24`. | | `timeFormat` | The form of time notation that will be used. Possible values are `12` or `24`. The default is `24`. |
| `units` | The units that will be used in the default weather modules. Possible values are `metric` or `imperial`. The default is `metric`. |
| `modules` | An array of active modules. **The array must contain objects. See the next table below for more information.** | | `modules` | An array of active modules. **The array must contain objects. See the next table below for more information.** |
Module configuration: Module configuration:

View File

@ -9,6 +9,7 @@ var config = {
language: 'en', language: 'en',
timeFormat: 24, timeFormat: 24,
units: 'metric',
modules: [ modules: [
{ {

View File

@ -6,9 +6,9 @@
* MIT Licensed. * * MIT Licensed. *
* * * *
* Add any custom CSS below. * * Add any custom CSS below. *
* Changes to this files will not be ignored by GIT. * * Changes to this files will be ignored by GIT. *
*****************************************************/ *****************************************************/
body { body {
} }

View File

@ -18,7 +18,7 @@
echo "Installing helper tools ..." echo "Installing helper tools ..."
sudo apt-get install curl wget build-essential unzip || exit sudo apt-get install curl wget build-essential unzip || exit
ARM=$(uname -m) # Determine which Pi is running. ARM=$(uname -m) # Determine which Pi is running.
NODE_LATEST="v5.11.0" # Set the latest version here. NODE_LATEST="v6.0.0" # Set the latest version here.
DOWNLOAD_URL="https://nodejs.org/dist/latest/node-$NODE_LATEST-linux-$ARM.tar.gz" # Construct the download URL. DOWNLOAD_URL="https://nodejs.org/dist/latest/node-$NODE_LATEST-linux-$ARM.tar.gz" # Construct the download URL.
echo "Installing Latest Node.js ..." echo "Installing Latest Node.js ..."

View File

@ -12,7 +12,8 @@ var defaults = {
language: "en", language: "en",
timeFormat: 24, timeFormat: 24,
units: "metric",
modules: [ modules: [
{ {
module: "helloworld", module: "helloworld",

View File

@ -21,6 +21,27 @@ var Log = (function() {
}, },
error: function(message) { error: function(message) {
console.error(message); console.error(message);
},
warn: function(message) {
console.warn(message);
},
group: function(message) {
console.group(message);
},
groupCollapsed: function(message) {
console.groupCollapsed(message);
},
groupEnd: function() {
console.groupEnd();
},
time: function(message) {
console.time(message);
},
timeEnd: function(message) {
console.timeEnd(message);
},
timeStamp: function(message) {
console.timeStamp(message);
} }
}; };
})(); })();

View File

@ -97,7 +97,7 @@ start: function() {
####`getScripts()` ####`getScripts()`
**Should return: Array** **Should return: Array**
The getScripts method is called to request any additional scripts that need to be loaded. This method should therefor return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder. The getScripts method is called to request any additional scripts that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
**Example:** **Example:**
````javascript ````javascript
@ -117,7 +117,7 @@ getScripts: function() {
####`getStyles()` ####`getStyles()`
**Should return: Array** **Should return: Array**
The getStyles method is called to request any additional scripts that need to be loaded. This method should therefor return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder. The getStyles method is called to request any additional stylesheets that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
**Example:** **Example:**
````javascript ````javascript
@ -133,6 +133,22 @@ getStyles: function() {
```` ````
**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls. **Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls.
####`getTranslations()`
**Should return: Dictionary**
The getTranslations method is called to request translation files that need to be loaded. This method should therefore return a dictionary with the files to load, identified by the country's short name.
**Example:**
````javascript
getTranslations: function() {
return {
en: "translations/en.json",
de: "translations/de.json"
}
}
````
####`getDom()` ####`getDom()`
**Should return:** Dom Object **Should return:** Dom Object
@ -261,6 +277,25 @@ To show a module, you can call the `show(speed, callback)` method. You can call
**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.<br> **Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.<br>
**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender). **Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender).
####`this.translate(identifier)`
***identifier* String** - Identifier of the string that should be translated.
The Magic Mirror contains a convenience wrapper for `l18n`. You can use this to automatically serve different translations for your modules based on the user's `language` configuration.
**Example:**
````javascript
this.translate("INFO") //Will return a translated string for the identifier INFO
````
**Example json file:**
````javascript
{
"INFO": "Really important information!"
}
````
**Note:** Currently there is no fallback if a translation identifier does not exist in one language. Right now you always have to add all identifier to all your translations even if they are not translated yet (see [#191](https://github.com/MichMich/MagicMirror/issues/191)).
## The Node Helper: node_helper.js ## The Node Helper: node_helper.js
@ -458,4 +493,4 @@ The Magic Mirror contains a convenience wrapper for logging. Currently, this log
Log.info('error'); Log.info('error');
Log.log('log'); Log.log('log');
Log.error('info'); Log.error('info');
``` ````

View File

@ -112,36 +112,6 @@ The following properties can be configured:
</code> </code>
</td> </td>
</tr> </tr>
<tr>
<td><code>loadingText</code></td>
<td>Text to display while loading item.<br>
<br><b>Default value:</b> <code>'Loading events &hellip;'</code>
</td>
</tr>
<tr>
<td><code>emptyCalendarText</code></td>
<td>Text to display when there are no upcoming events.<br>
<br><b>Default value:</b> <code>'No upcoming events.'</code>
</td>
</tr>
<tr>
<td><code>todayText</code></td>
<td>Text to display when a fullday event is planned for today.<br>
<br><b>Default value:</b> <code>'Today'</code>
</td>
</tr>
<tr>
<td><code>tomorrowText</code></td>
<td>Text to display when a fullday event is planned for tomorrow.<br>
<br><b>Default value:</b> <code>'Tomorrow'</code>
</td>
</tr>
<tr>
<td><code>runningText</code></td>
<td>Text to display when an event is still running.<br>
<br><b>Default value:</b> <code>'Ends in'</code>
</td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@ -124,7 +124,7 @@ Module.register("calendar",{
if (event.fullDayEvent) { if (event.fullDayEvent) {
if (event.today) { if (event.today) {
timeWrapper.innerHTML = this.translate("TODAY"); timeWrapper.innerHTML = this.translate("TODAY");
} else if (event.startDate - now < 24 * 60 * 60 * 1000) { } else if (event.startDate - now < 24 * 60 * 60 * 1000 && event.startDate - now > 0) {
timeWrapper.innerHTML = this.translate("TOMORROW"); timeWrapper.innerHTML = this.translate("TOMORROW");
} else { } else {
timeWrapper.innerHTML = moment(event.startDate,"x").fromNow(); timeWrapper.innerHTML = moment(event.startDate,"x").fromNow();
@ -141,7 +141,8 @@ Module.register("calendar",{
timeWrapper.innerHTML = this.translate("RUNNING") + ' ' + moment(event.endDate,"x").fromNow(true); timeWrapper.innerHTML = this.translate("RUNNING") + ' ' + moment(event.endDate,"x").fromNow(true);
} }
} }
// timeWrapper.innerHTML = moment(event.startDate,'x').format('lll'); //timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
//console.log(event);
timeWrapper.className = "time light"; timeWrapper.className = "time light";
eventWrapper.appendChild(timeWrapper); eventWrapper.appendChild(timeWrapper);

View File

@ -99,7 +99,7 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
continue; continue;
} }
if (fullDayEvent && endDate < today) { if (fullDayEvent && endDate <= today) {
//console.log("It's a fullday event, and it is before today. So skip: " + title); //console.log("It's a fullday event, and it is before today. So skip: " + title);
continue; continue;
} }

View File

@ -1,7 +1,7 @@
{ {
"TODAY": "Heute" "TODAY": "Heute"
, "TOMORROW": "Morgen" , "TOMORROW": "Morgen"
, "RUNNING": "Endet in" , "RUNNING": "noch"
, "LOADING": "Lade Termine &hellip;" , "LOADING": "Lade Termine &hellip;"
, "EMPTY": "Keine Termine." , "EMPTY": "Keine Termine."
} }

View File

@ -28,6 +28,14 @@ ical.objectHandlers['END'] = function(val, params, curr, stack){
if (curr.rrule) { if (curr.rrule) {
var rule = curr.rrule.replace('RRULE:', ''); var rule = curr.rrule.replace('RRULE:', '');
if (rule.indexOf('DTSTART') === -1) { if (rule.indexOf('DTSTART') === -1) {
if (curr.start.length === 8) {
var comps = /^(\d{4})(\d{2})(\d{2})$/.exec(curr.start);
if (comps) {
curr.start = new Date (comps[1], comps[2], comps[3]);
}
}
rule += ';DTSTART=' + curr.start.toISOString().replace(/[-:]/g, ''); rule += ';DTSTART=' + curr.start.toISOString().replace(/[-:]/g, '');
rule = rule.replace(/\.[0-9]{3}/, ''); rule = rule.replace(/\.[0-9]{3}/, '');
} }

View File

@ -47,14 +47,21 @@ The following properties can be configured:
</tr> </tr>
<tr> <tr>
<td><code>showPeriod</code></td> <td><code>showPeriod</code></td>
<td>Show the period (am/pm) with 12 hour format<br> <td>Show the period (am/pm) with 12 hour format.<br>
<br><b>Possible values:</b> <code>true</code> or <code>false</code> <br><b>Possible values:</b> <code>true</code> or <code>false</code>
<br><b>Default value:</b> <code>true</code> <br><b>Default value:</b> <code>true</code>
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>showPeriodUpper</code></td> <td><code>showPeriodUpper</code></td>
<td>Show the period (AM/PM) with 12 hour format as uppercase<br> <td>Show the period (AM/PM) with 12 hour format as uppercase.<br>
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
<br><b>Default value:</b> <code>false</code>
</td>
</tr>
<tr>
<td><code>clockBold</code></td>
<td>Remove the colon and bold the minutes to make a more modern look.<br>
<br><b>Possible values:</b> <code>true</code> or <code>false</code> <br><b>Possible values:</b> <code>true</code> or <code>false</code>
<br><b>Default value:</b> <code>false</code> <br><b>Default value:</b> <code>false</code>
</td> </td>

View File

@ -1,41 +1,34 @@
/* global Log, Module, moment, config */ /* global Log, Module, moment, config */
/* Magic Mirror /* Magic Mirror
* Module: Clock * Module: Clock
* *
* By Michael Teeuw http://michaelteeuw.nl * By Michael Teeuw http://michaelteeuw.nl
* MIT Licensed. * MIT Licensed.
*/ */
Module.register("clock",{ Module.register("clock",{
// Module config defaults. // Module config defaults.
defaults: { defaults: {
timeFormat: config.timeFormat, timeFormat: config.timeFormat,
displaySeconds: true, displaySeconds: true,
showPeriod: true, showPeriod: true,
showPeriodUpper: false, showPeriodUpper: false,
clockBold: false
}, },
// Define required scripts. // Define required scripts.
getScripts: function() { getScripts: function() {
return ["moment.js"]; return ["moment.js"];
}, },
// Define start sequence. // Define start sequence.
start: function() { start: function() {
Log.info("Starting module: " + this.name); Log.info("Starting module: " + this.name);
// Schedule update interval. // Schedule update interval.
var self = this; var self = this;
setInterval(function() { setInterval(function() {
self.updateDom(); self.updateDom();
}, 1000); }, 1000);
// Set locale. // Set locale.
moment.locale(config.language); moment.locale(config.language);
}, },
// Override dom generator. // Override dom generator.
getDom: function() { getDom: function() {
// Create wrappers. // Create wrappers.
@ -44,35 +37,36 @@ Module.register("clock",{
var timeWrapper = document.createElement("div"); var timeWrapper = document.createElement("div");
var secondsWrapper = document.createElement("sup"); var secondsWrapper = document.createElement("sup");
var periodWrapper = document.createElement("span"); var periodWrapper = document.createElement("span");
// Style Wrappers // Style Wrappers
dateWrapper.className = "date normal medium"; dateWrapper.className = "date normal medium";
timeWrapper.className = "time bright large light"; timeWrapper.className = "time bright large light";
secondsWrapper.className = "dimmed"; secondsWrapper.className = "dimmed";
// Set content of wrappers. // Set content of wrappers.
// The moment().format('h') method has a bug on the Raspberry Pi. // The moment().format("h") method has a bug on the Raspberry Pi.
// So we need to generate the timestring manually. // So we need to generate the timestring manually.
// See issue: https://github.com/MichMich/MagicMirror/issues/181 // See issue: https://github.com/MichMich/MagicMirror/issues/181
var timeString = moment().format('HH:mm'); if (this.config.clockBold === true) {
var timeString = moment().format("HH[<span class=\"bold\">]mm[</span>]");
} else {
var timeString = moment().format("HH:mm");
}
if (this.config.timeFormat !== 24) { if (this.config.timeFormat !== 24) {
var now = new Date(); var now = new Date();
var hours = now.getHours() % 12 || 12; var hours = now.getHours() % 12 || 12;
timeString = hours + moment().format(':mm'); if (this.config.clockBold === true) {
timeString = hours + moment().format("[<span class=\"bold\">]mm[</span>]");
} else {
timeString = hours + moment().format(":mm");
}
} }
dateWrapper.innerHTML = moment().format("dddd, LL"); dateWrapper.innerHTML = moment().format("dddd, LL");
timeWrapper.innerHTML = timeString; timeWrapper.innerHTML = timeString;
secondsWrapper.innerHTML = moment().format("ss"); secondsWrapper.innerHTML = moment().format("ss");
if (this.config.showPeriodUpper) { if (this.config.showPeriodUpper) {
periodWrapper.innerHTML = moment().format('A'); periodWrapper.innerHTML = moment().format("A");
} else { } else {
periodWrapper.innerHTML = moment().format('a'); periodWrapper.innerHTML = moment().format("a");
} }
// Combine wrappers. // Combine wrappers.
wrapper.appendChild(dateWrapper); wrapper.appendChild(dateWrapper);
wrapper.appendChild(timeWrapper); wrapper.appendChild(timeWrapper);
@ -82,7 +76,6 @@ Module.register("clock",{
if (this.config.showPeriod && this.config.timeFormat !== 24) { if (this.config.showPeriod && this.config.timeFormat !== 24) {
timeWrapper.appendChild(periodWrapper); timeWrapper.appendChild(periodWrapper);
} }
// Return the wrapper to the dom. // Return the wrapper to the dom.
return wrapper; return wrapper;
} }

View File

@ -50,9 +50,9 @@ The following properties can be configured:
</tr> </tr>
<tr> <tr>
<td><code>units</code></td> <td><code>units</code></td>
<td>What units to use?<br> <td>What units to use. Specified by config.js<br>
<br><b>Possible values:</b> <code>default</code> = Kelvin, <code>metric</code> = Celsius, <code>imperial</code> =Fahrenheit <br><b>Possible values:</b> <code>config.units</code> = Specified by config.js, <code>default</code> = Kelvin, <code>metric</code> = Celsius, <code>imperial</code> =Fahrenheit
<br><b>Default value:</b> <code>metric</code> <br><b>Default value:</b> <code>config.units</code>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -90,6 +90,13 @@ The following properties can be configured:
<br><b>Default value:</b> <code>false</code> <br><b>Default value:</b> <code>false</code>
</td> </td>
</tr> </tr>
<tr>
<td><code>showWindDirection</code></td>
<td>Show the wind direction next to the wind speed.<br>
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
<br><b>Default value:</b> <code>false</code>
</td>
</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>

View File

@ -13,12 +13,13 @@ Module.register("currentweather",{
defaults: { defaults: {
location: "", location: "",
appid: "", appid: "",
units: "metric", units: config.units,
updateInterval: 10 * 60 * 1000, // every 10 minutes updateInterval: 10 * 60 * 1000, // every 10 minutes
animationSpeed: 1000, animationSpeed: 1000,
timeFormat: config.timeFormat, timeFormat: config.timeFormat,
showPeriod: true, showPeriod: true,
showPeriodUpper: false, showPeriodUpper: false,
showWindDirection: false,
lang: config.language, lang: config.language,
initialLoadDelay: 0, // 0 seconds delay initialLoadDelay: 0, // 0 seconds delay
@ -68,6 +69,7 @@ Module.register("currentweather",{
moment.locale(config.language); moment.locale(config.language);
this.windSpeed = null; this.windSpeed = null;
this.windDirection = null;
this.sunriseSunsetTime = null; this.sunriseSunsetTime = null;
this.sunriseSunsetIcon = null; this.sunriseSunsetIcon = null;
this.temperature = null; this.temperature = null;
@ -108,11 +110,16 @@ Module.register("currentweather",{
var windIcon = document.createElement("span"); var windIcon = document.createElement("span");
windIcon.className = "wi wi-strong-wind dimmed"; windIcon.className = "wi wi-strong-wind dimmed";
small.appendChild(windIcon); small.appendChild(windIcon);
var windSpeed = document.createElement("span"); var windSpeed = document.createElement("span");
windSpeed.innerHTML = " " + this.windSpeed; windSpeed.innerHTML = " " + this.windSpeed;
small.appendChild(windSpeed); small.appendChild(windSpeed);
if (this.config.showWindDirection) {
var windDirection = document.createElement("span");
windDirection.innerHTML = " " + this.windDirection;
small.appendChild(windDirection);
}
var spacer = document.createElement("span"); var spacer = document.createElement("span");
spacer.innerHTML = "&nbsp;"; spacer.innerHTML = "&nbsp;";
small.appendChild(spacer); small.appendChild(spacer);
@ -198,6 +205,7 @@ Module.register("currentweather",{
processWeather: function(data) { processWeather: function(data) {
this.temperature = this.roundValue(data.main.temp); this.temperature = this.roundValue(data.main.temp);
this.windSpeed = this.ms2Beaufort(this.roundValue(data.wind.speed)); this.windSpeed = this.ms2Beaufort(this.roundValue(data.wind.speed));
this.windDirection = this.deg2Cardinal(data.wind.deg);
this.weatherType = this.config.iconTable[data.weather[0].icon]; this.weatherType = this.config.iconTable[data.weather[0].icon];
var now = new Date(); var now = new Date();
@ -274,6 +282,44 @@ Module.register("currentweather",{
* *
* return number - Rounded Temperature. * return number - Rounded Temperature.
*/ */
deg2Cardinal: function(deg) {
if (deg>11.25 && deg<33.75){
return "NNE";
}else if (deg>33.75 && deg<56.25){
return "ENE";
}else if (deg>56.25 && deg<78.75){
return "E";
}else if (deg>78.75 && deg<101.25){
return "ESE";
}else if (deg>101.25 && deg<123.75){
return "ESE";
}else if (deg>123.75 && deg<146.25){
return "SE";
}else if (deg>146.25 && deg<168.75){
return "SSE";
}else if (deg>168.75 && deg<191.25){
return "S";
}else if (deg>191.25 && deg<213.75){
return "SSW";
}else if (deg>213.75 && deg<236.25){
return "SW";
}else if (deg>236.25 && deg<258.75){
return "WSW";
}else if (deg>258.75 && deg<281.25){
return "W";
}else if (deg>281.25 && deg<303.75){
return "WNW";
}else if (deg>303.75 && deg<326.25){
return "NW";
}else if (deg>326.25 && deg<348.75){
return "NNW";
}else{
return "N";
}
},
roundValue: function(temperature) { roundValue: function(temperature) {
return parseFloat(temperature).toFixed(1); return parseFloat(temperature).toFixed(1);
} }

View File

@ -50,9 +50,17 @@ The following properties can be configured:
</tr> </tr>
<tr> <tr>
<td><code>units</code></td> <td><code>units</code></td>
<td>What units to use?<br> <td>What units to use. Specified by config.js<br>
<br><b>Possible values:</b> <code>default</code> = Kelvin, <code>metric</code> = Celsius, <code>imperial</code> =Fahrenheit <br><b>Possible values:</b> <code>config.units</code> = Specified by config.js, <code>default</code> = Kelvin, <code>metric</code> = Celsius, <code>imperial</code> =Fahrenheit
<br><b>Default value:</b> <code>metric</code> <br><b>Default value:</b> <code>config.units</code>
</td>
</tr>
<tr>
<td><code>maxNumberOfDays</code></td>
<td>How many days of forecast to return. Specified by config.js<br>
<br><b>Possible values:</b> <code>1</code> - <code>16</code>
<br><b>Default value:</b> <code>7</code> (7 days)
<br>This value is optional. By default the weatherforecast module will return 7 days.
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -13,7 +13,8 @@ Module.register("weatherforecast",{
defaults: { defaults: {
location: "", location: "",
appid: "", appid: "",
units: "metric", units: config.units,
maxNumberOfDays: 7,
updateInterval: 10 * 60 * 1000, // every 10 minutes updateInterval: 10 * 60 * 1000, // every 10 minutes
animationSpeed: 1000, animationSpeed: 1000,
timeFormat: config.timeFormat, timeFormat: config.timeFormat,
@ -189,6 +190,12 @@ Module.register("weatherforecast",{
params += "q=" + this.config.location; params += "q=" + this.config.location;
params += "&units=" + this.config.units; params += "&units=" + this.config.units;
params += "&lang=" + this.config.lang; params += "&lang=" + this.config.lang;
/*
* Submit a specific number of days to forecast, between 1 to 16 days.
* The OpenWeatherMap API properly handles values outside of the 1 - 16 range and returns 7 days by default.
* This is simply being pedantic and doing it ourselves.
*/
params += "&cnt=" + (((this.config.maxNumberOfDays < 1) || (this.config.maxNumberOfDays > 16)) ? 7 : this.config.maxNumberOfDays);
params += "&APPID=" + this.config.appid; params += "&APPID=" + this.config.appid;
return params; return params;