mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 11:50:00 +00:00
commit
55464ed0dd
@ -1,6 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "7"
|
||||
- "8"
|
||||
before_script:
|
||||
- yarn danger ci
|
||||
- npm install grunt-cli -g
|
||||
|
14
CHANGELOG.md
14
CHANGELOG.md
@ -9,11 +9,25 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
*This release is scheduled to be released on 2019-04-01.*
|
||||
|
||||
ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
|
||||
|
||||
### Added
|
||||
|
||||
### Updated
|
||||
- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500)
|
||||
|
||||
### Fixed
|
||||
- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503).
|
||||
- Fixed unhandled error on bad git data in updatenotiifcation module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
|
||||
- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504).
|
||||
|
||||
### New weather module
|
||||
- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
|
||||
- Dimmed loading indicator for weather forecast.
|
||||
- Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
|
||||
- Aligned indoor values in current weather vertical [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
|
||||
- Added humidity support to nunjuck unit filter.
|
||||
- Do not display degree symbol for temperature in Kelvin [#1503](https://github.com/MichMich/MagicMirror/issues/1503).
|
||||
|
||||
## [2.6.0] - 2019-01-01
|
||||
|
||||
|
@ -201,13 +201,13 @@ Module.register("currentweather",{
|
||||
if (this.config.degreeLabel) {
|
||||
switch (this.config.units ) {
|
||||
case "metric":
|
||||
degreeLabel = "C";
|
||||
degreeLabel = " °C";
|
||||
break;
|
||||
case "imperial":
|
||||
degreeLabel = "F";
|
||||
degreeLabel = " °F";
|
||||
break;
|
||||
case "default":
|
||||
degreeLabel = "K";
|
||||
degreeLabel = " K";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -218,7 +218,7 @@ Module.register("currentweather",{
|
||||
|
||||
var temperature = document.createElement("span");
|
||||
temperature.className = "bright";
|
||||
temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + "°" + degreeLabel;
|
||||
temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + degreeLabel;
|
||||
large.appendChild(temperature);
|
||||
|
||||
if (this.config.showIndoorTemperature && this.indoorTemperature) {
|
||||
@ -228,7 +228,7 @@ Module.register("currentweather",{
|
||||
|
||||
var indoorTemperatureElem = document.createElement("span");
|
||||
indoorTemperatureElem.className = "bright";
|
||||
indoorTemperatureElem.innerHTML = " " + this.indoorTemperature.replace(".", this.config.decimalSymbol) + "°" + degreeLabel;
|
||||
indoorTemperatureElem.innerHTML = " " + this.indoorTemperature.replace(".", this.config.decimalSymbol) + degreeLabel;
|
||||
large.appendChild(indoorTemperatureElem);
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ Module.register("currentweather",{
|
||||
|
||||
var feelsLike = document.createElement("span");
|
||||
feelsLike.className = "dimmed";
|
||||
feelsLike.innerHTML = this.translate("FEELS") + " " + this.feelsLike + "°" + degreeLabel;
|
||||
feelsLike.innerHTML = this.translate("FEELS") + " " + this.feelsLike + degreeLabel;
|
||||
small.appendChild(feelsLike);
|
||||
|
||||
wrapper.appendChild(small);
|
||||
|
@ -65,8 +65,10 @@ module.exports = NodeHelper.create({
|
||||
data.module = sg.module;
|
||||
if (!err) {
|
||||
sg.git.log({"-1": null}, function(err, data2) {
|
||||
data.hash = data2.latest.hash;
|
||||
self.sendSocketNotification("STATUS", data);
|
||||
if (!err && data2.latest && "hash" in data2.latest) {
|
||||
data.hash = data2.latest.hash;
|
||||
self.sendSocketNotification("STATUS", data);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -78,7 +78,7 @@ The following properties can be configured:
|
||||
| ---------------------------- | -----------
|
||||
| `apiVersion` | The OpenWeatherMap API version to use. <br><br> **Default value:** `2.5`
|
||||
| `apiBase` | The OpenWeatherMap base URL. <br><br> **Default value:** `'http://api.openweathermap.org/data/'`
|
||||
| `weatherEndpoint` | The OpenWeatherMap API endPoint. <br><br> **Possible values:** `/weather` or `/forecast/daily` <br> **Default value:** `'/weather'`
|
||||
| `weatherEndpoint` | The OpenWeatherMap API endPoint. <br><br> **Possible values:** `/weather`, `/forecast` or `/forecast/daily` (paying users only) <br> **Default value:** `'/weather'`
|
||||
| `locationID` | Location ID from [OpenWeatherMap](https://openweathermap.org/find) **This will override anything you put in location.** <br> Leave blank if you want to use location. <br> **Example:** `1234567` <br> **Default value:** `false` <br><br> **Note:** When the `location` and `locationID` 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.
|
||||
| `location` | The location used for weather information. <br><br> **Example:** `'Amsterdam,Netherlands'` <br> **Default value:** `false` <br><br> **Note:** When the `location` and `locationID` 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.
|
||||
| `apiKey` | The [OpenWeatherMap](https://home.openweathermap.org) API key, which can be obtained by creating an OpenWeatherMap account. <br><br> This value is **REQUIRED**
|
||||
|
@ -4,31 +4,30 @@
|
||||
<span class="wi wi-strong-wind dimmed"></span>
|
||||
<span>
|
||||
{% if config.useBeaufort %}
|
||||
{{current.beaufortWindSpeed() | round}}
|
||||
{{ current.beaufortWindSpeed() | round }}
|
||||
{% else %}
|
||||
{{current.windSpeed | round}}
|
||||
{{ current.windSpeed | round }}
|
||||
{% endif %}
|
||||
|
||||
{% if config.showWindDirection %}
|
||||
<sup>
|
||||
{% if config.showWindDirectionAsArrow %}
|
||||
<i class="fa fa-long-arrow-up" style="transform:rotate({{current.windDirection}}deg);"></i>
|
||||
<i class="fa fa-long-arrow-up" style="transform:rotate({{ current.windDirection }}deg);"></i>
|
||||
{% else %}
|
||||
{{current.cardinalWindDirection() | translate}}
|
||||
{{ current.cardinalWindDirection() | translate }}
|
||||
{% endif %}
|
||||
|
||||
</sup>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if config.showHumidity and current.humidity %}
|
||||
<span>{{ current.humidity }}</span><sup> <i class="wi wi-humidity humidityIcon"></i></sup>
|
||||
<span>{{ current.humidity | decimalSymbol }}</span><sup> <i class="wi wi-humidity humidityIcon"></i></sup>
|
||||
{% endif %}
|
||||
<span class="wi dimmed wi-{{current.nextSunAction()}}"></span>
|
||||
<span class="wi dimmed wi-{{ current.nextSunAction() }}"></span>
|
||||
<span>
|
||||
{% if current.nextSunAction() == "sunset" %}
|
||||
{{current.sunset | formatTime}}
|
||||
{{ current.sunset | formatTime }}
|
||||
{% else %}
|
||||
{{current.sunrise | formatTime}}
|
||||
{{ current.sunrise | formatTime }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
@ -36,31 +35,37 @@
|
||||
<div class="large light">
|
||||
<span class="wi weathericon wi-{{current.weatherType}}"></span>
|
||||
<span class="bright">
|
||||
{{current.temperature | roundValue | unit("temperature")}}
|
||||
{{ current.temperature | roundValue | unit("temperature") | decimalSymbol }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="normal light indoor">
|
||||
{% if config.showIndoorTemperature and indoor.temperature %}
|
||||
<span class="fa fa-home"></span>
|
||||
<span class="bright">
|
||||
{{indoor.temperature | roundValue | unit("temperature")}}
|
||||
</span>
|
||||
<div>
|
||||
<span class="fa fa-home"></span>
|
||||
<span class="bright">
|
||||
{{ indoor.temperature | roundValue | unit("temperature") | decimalSymbol }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if config.showIndoorHumidity and indoor.humidity %}
|
||||
<span class="fa fa-tint"></span>
|
||||
<span class="bright">
|
||||
{{indoor.humidity | roundValue}}%
|
||||
</span>
|
||||
<div>
|
||||
<span class="fa fa-tint"></span>
|
||||
<span class="bright">
|
||||
{{ indoor.humidity | roundValue | unit("humidity") | decimalSymbol }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if config.showFeelsLike and not config.onlyTemp %}
|
||||
<div class="normal medium">
|
||||
<span class="dimmed">
|
||||
{{ "FEELS" | translate }} {{ current.feelsLike() | roundValue | unit("temperature") }}
|
||||
{{ "FEELS" | translate }} {{ current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="dimmed light small">
|
||||
{{"LOADING" | translate}}
|
||||
{{ "LOADING" | translate }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
@ -1,25 +1,27 @@
|
||||
{% if forecast %}
|
||||
<table class="{{config.tableClass}}">
|
||||
<table class="{{ config.tableClass }}">
|
||||
{% for f in forecast %}
|
||||
<tr {% if config.colored %}class="colored"{% endif %}>
|
||||
<td class="day">{{f.date.format('ddd')}}</td>
|
||||
<td class="bright weather-icon"><span class="wi weathericon wi-{{f.weatherType}}"></span></td>
|
||||
<td class="day">{{ f.date.format('ddd') }}</td>
|
||||
<td class="bright weather-icon"><span class="wi weathericon wi-{{ f.weatherType }}"></span></td>
|
||||
<td class="align-right bright max-temp">
|
||||
{{f.maxTemperature | roundValue | unit("temperature")}}
|
||||
{{ f.maxTemperature | roundValue | unit("temperature") }}
|
||||
</td>
|
||||
<td class="align-right min-temp">
|
||||
{{f.minTemperature | roundValue | unit("temperature")}}
|
||||
{{ f.minTemperature | roundValue | unit("temperature") }}
|
||||
</td>
|
||||
{% if config.showRainAmount %}
|
||||
<td class="align-right bright rain">
|
||||
{{f.rain | unit("rain")}}
|
||||
{{ f.rain | unit("rain") }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
{{"LOADING" | translate}}
|
||||
<div class="dimmed light small">
|
||||
{{ "LOADING" | translate }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Unclomment the line below to see the contents of the `current` object. -->
|
||||
|
@ -87,25 +87,64 @@ WeatherProvider.register("openweathermap", {
|
||||
* Generate WeatherObjects based on forecast information
|
||||
*/
|
||||
generateWeatherObjectsFromForecast(forecasts) {
|
||||
// initial variable declaration
|
||||
const days = [];
|
||||
// variables for temperature range and rain
|
||||
var minTemp = [];
|
||||
var maxTemp = [];
|
||||
var rain = 0;
|
||||
// variable for date
|
||||
let date = "";
|
||||
var weather = new WeatherObject(this.config.units);
|
||||
|
||||
for (const forecast of forecasts) {
|
||||
const weather = new WeatherObject(this.config.units);
|
||||
|
||||
weather.date = moment(forecast.dt, "X");
|
||||
weather.minTemperature = forecast.temp.min;
|
||||
weather.maxTemperature = forecast.temp.max;
|
||||
weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
|
||||
if (this.config.units === "imperial" && !isNaN(forecast.rain)) {
|
||||
weather.rain = forecast.rain / 25.4
|
||||
|
||||
if (date === moment(forecast.dt, "X").format("YYYY-MM-DD")) {
|
||||
// the same day as before
|
||||
// add values from forecast to corresponding variables
|
||||
minTemp.push(forecast.main.temp_min);
|
||||
maxTemp.push(forecast.main.temp_max);
|
||||
if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) {
|
||||
rain += forecast.rain["3h"] / 25.4;
|
||||
} else {
|
||||
rain += forecast.rain["3h"];
|
||||
}
|
||||
} else {
|
||||
weather.rain = forecast.rain;
|
||||
// a new day
|
||||
// calculate minimum/maximum temperature, specify rain amount
|
||||
weather.minTemperature = Math.min.apply(null, minTemp);
|
||||
weather.maxTemperature = Math.max.apply(null, maxTemp);
|
||||
weather.rain = rain;
|
||||
// push weather information to days array
|
||||
days.push(weather);
|
||||
// create new weather-object
|
||||
weather = new WeatherObject(this.config.units);
|
||||
|
||||
minTemp = [];
|
||||
maxTemp = [];
|
||||
rain *= 0;
|
||||
|
||||
// set new date
|
||||
date = moment(forecast.dt, "X").format("YYYY-MM-DD");
|
||||
|
||||
// specify date
|
||||
weather.date = moment(forecast.dt, "X");
|
||||
|
||||
// select weather type by first forecast value of a day, is this reasonable?
|
||||
weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
|
||||
|
||||
// add values from first forecast of this day to corresponding variables
|
||||
minTemp.push(forecast.main.temp_min);
|
||||
maxTemp.push(forecast.main.temp_max);
|
||||
if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) {
|
||||
rain += forecast.rain["3h"] / 25.4;
|
||||
} else {
|
||||
rain += forecast.rain["3h"];
|
||||
}
|
||||
}
|
||||
|
||||
days.push(weather);
|
||||
}
|
||||
|
||||
return days;
|
||||
|
||||
return days.slice(1);
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -36,6 +36,10 @@
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.weather tr .weathericon {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.weather tr.colored .min-temp {
|
||||
color: #bcddff;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ Module.register("weather",{
|
||||
lang: config.language,
|
||||
showHumidity: false,
|
||||
degreeLabel: false,
|
||||
decimalSymbol: ".",
|
||||
showIndoorTemperature: false,
|
||||
showIndoorHumidity: false,
|
||||
|
||||
@ -184,7 +185,9 @@ Module.register("weather",{
|
||||
|
||||
this.nunjucksEnvironment().addFilter("unit", function (value, type) {
|
||||
if (type === "temperature") {
|
||||
value += "°";
|
||||
if (this.config.units === "metric" || this.config.units === "imperial") {
|
||||
value += "°";
|
||||
}
|
||||
if (this.config.degreeLabel) {
|
||||
if (this.config.units === "metric") {
|
||||
value += "C";
|
||||
@ -200,6 +203,8 @@ Module.register("weather",{
|
||||
} else {
|
||||
value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`;
|
||||
}
|
||||
} else if (type === "humidity") {
|
||||
value += "%"
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -208,5 +213,9 @@ Module.register("weather",{
|
||||
this.nunjucksEnvironment().addFilter("roundValue", function(value) {
|
||||
return this.roundValue(value);
|
||||
}.bind(this));
|
||||
|
||||
this.nunjucksEnvironment().addFilter("decimalSymbol", function(value) {
|
||||
return value.replace(/\./g, this.config.decimalSymbol);
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
|
@ -142,17 +142,17 @@ Module.register("weatherforecast",{
|
||||
icon.className = "wi weathericon " + forecast.icon;
|
||||
iconCell.appendChild(icon);
|
||||
|
||||
var degreeLabel = "°";
|
||||
var degreeLabel = "";
|
||||
if(this.config.scale) {
|
||||
switch(this.config.units) {
|
||||
case "metric":
|
||||
degreeLabel += " C";
|
||||
degreeLabel = " °C";
|
||||
break;
|
||||
case "imperial":
|
||||
degreeLabel += " F";
|
||||
degreeLabel = " °F";
|
||||
break;
|
||||
case "default":
|
||||
degreeLabel = "K";
|
||||
degreeLabel = " K";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
711
package-lock.json
generated
711
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@
|
||||
"ajv": "6.5.5",
|
||||
"body-parser": "^1.18.2",
|
||||
"colors": "^1.1.2",
|
||||
"electron": "^2.0.16",
|
||||
"electron": "^3.0.13",
|
||||
"express": "^4.16.2",
|
||||
"express-ipfilter": "0.3.1",
|
||||
"feedme": "latest",
|
||||
|
@ -36,7 +36,7 @@ describe("Electron app environment", function() {
|
||||
it("should open a browserwindow", function() {
|
||||
return app.client
|
||||
.waitUntilWindowLoaded()
|
||||
.browserWindow.focus()
|
||||
// .browserWindow.focus()
|
||||
.getWindowCount()
|
||||
.should.eventually.equal(1)
|
||||
.browserWindow.isMinimized()
|
||||
|
Loading…
x
Reference in New Issue
Block a user