diff --git a/.gitignore b/.gitignore index f1a6aeb3..6942715f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,7 @@ lib-cov coverage .lock-wscript build/Release -/node_modules/**/* -!/tests/node_modules/**/* +node_modules jspm_modules .npm .node_repl_history @@ -56,21 +55,15 @@ Temporary Items .Trash-* # Ignore all modules except the default modules. -/modules/** -!/modules/default -!/modules/default/** -!/modules/README.md** +modules +!modules/default -# Ignore changes to the custom css files but keep the sample and main. -/css/* -!/css/custom.css.sample -!/css/main.css -!/css/roboto.css -!/css/font-awesome.css +# Ignore changes to the custom css files but keep others. +css/custom.css # Ignore users config file but keep the sample. -/config/* -!/config/config.js.sample +config +!config/config.js.sample # Vim ## swap diff --git a/CHANGELOG.md b/CHANGELOG.md index 8db90470..48c5f559 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ planned for 2026-01-01 - [weather] feat: add configurable forecast date format option (#3918) - [core] Add new `server:watch` script to run MagicMirror² server-only with automatic restarts when files (defined in `config.watchTargets`) change (#3920) +### Removed + +- [weather] Removed deprecated ukmetoffice datapoint provider (#3842, #3952) + ### Changed - [core] refactor: replace `module-alias` dependency with internal alias resolver (#3893) @@ -37,7 +41,7 @@ planned for 2026-01-01 ### Updated -- [core] Update dependencies (#3909, #3916, #3921, #3925, #3934) +- [core] Update dependencies incl. electron to v39 (#3909, #3916, #3921, #3925, #3934) - [logger] Add prefixes to most Log messages (#3923, #3926) ## [2.33.0] - 2025-10-01 diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js deleted file mode 100644 index b660a7b6..00000000 --- a/modules/default/weather/providers/ukmetoffice.js +++ /dev/null @@ -1,211 +0,0 @@ -/* global WeatherProvider, WeatherObject, WeatherUtils */ - -/* - * This class is a provider for UK Met Office Datapoint, - * see https://www.metoffice.gov.uk/ - */ -WeatherProvider.register("ukmetoffice", { - - /* - * 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: "UK Met Office", - - // Set the default config properties that is specific to this provider - defaults: { - apiBase: "http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/", - locationID: false, - apiKey: "" - }, - - // Overwrite the fetchCurrentWeather method. - fetchCurrentWeather () { - this.fetchData(this.getUrl("3hourly")) - .then((data) => { - if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { - - /* - * Did not receive usable new data. - * Maybe this needs a better check? - */ - return; - } - - this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`); - - const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); - this.setCurrentWeather(currentWeather); - }) - .catch(function (request) { - Log.error("[weatherprovider.ukmetoffice] Could not load data ... ", request); - }) - .finally(() => this.updateAvailable()); - }, - - // Overwrite the fetchCurrentWeather method. - fetchWeatherForecast () { - this.fetchData(this.getUrl("daily")) - .then((data) => { - if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { - - /* - * Did not receive usable new data. - * Maybe this needs a better check? - */ - return; - } - - this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`); - - const forecast = this.generateWeatherObjectsFromForecast(data); - this.setWeatherForecast(forecast); - }) - .catch(function (request) { - Log.error("[weatherprovider.ukmetoffice] Could not load data ... ", request); - }) - .finally(() => this.updateAvailable()); - }, - - /** UK Met Office Specific Methods - These are not part of the default provider methods */ - /* - * Gets the complete url for the request - */ - getUrl (forecastType) { - return this.config.apiBase + this.config.locationID + this.getParams(forecastType); - }, - - /* - * Generate a WeatherObject based on currentWeatherInformation - */ - generateWeatherObjectFromCurrentWeather (currentWeatherData) { - const currentWeather = new WeatherObject(); - const location = currentWeatherData.SiteRep.DV.Location; - - // data times are always UTC - let nowUtc = moment.utc(); - let midnightUtc = nowUtc.clone().startOf("day"); - let timeInMins = nowUtc.diff(midnightUtc, "minutes"); - - // loop round each of the (5) periods, look for today (the first period may be yesterday) - for (const period of location.Period) { - const periodDate = moment.utc(period.value.substr(0, 10), "YYYY-MM-DD"); - - // ignore if period is before today - if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { - // check this is the period we want, after today the diff will be -ve - if (moment().diff(periodDate, "minutes") > 0) { - - /* - * loop round the reports looking for the one we are in - * $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260 - */ - for (const rep of period.Rep) { - const p = rep.$; - if (timeInMins >= p && timeInMins - 180 < p) { - // finally got the one we want, so populate weather object - currentWeather.humidity = rep.H; - currentWeather.temperature = rep.T; - currentWeather.feelsLikeTemp = rep.F; - currentWeather.precipitationProbability = parseInt(rep.Pp); - currentWeather.windSpeed = WeatherUtils.convertWindToMetric(rep.S); - currentWeather.windFromDirection = WeatherUtils.convertWindDirection(rep.D); - currentWeather.weatherType = this.convertWeatherType(rep.W); - } - } - } - } - } - - // determine the sunrise/sunset times - not supplied in UK Met Office data - currentWeather.updateSunTime(location.lat, location.lon); - - return currentWeather; - }, - - /* - * Generate WeatherObjects based on forecast information - */ - generateWeatherObjectsFromForecast (forecasts) { - const days = []; - - /* - * loop round the (5) periods getting the data - * for each period array, Day is [0], Night is [1] - */ - for (const period of forecasts.SiteRep.DV.Location.Period) { - const weather = new WeatherObject(); - - // data times are always UTC - const dateStr = period.value; - let periodDate = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); - - // ignore if period is before today - if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { - // populate the weather object - weather.date = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); - weather.minTemperature = period.Rep[1].Nm; - weather.maxTemperature = period.Rep[0].Dm; - weather.weatherType = this.convertWeatherType(period.Rep[0].W); - weather.precipitationProbability = parseInt(period.Rep[0].PPd); - - days.push(weather); - } - } - - return days; - }, - - /* - * Convert the Met Office icons to a more usable name. - */ - convertWeatherType (weatherType) { - const weatherTypes = { - 0: "night-clear", - 1: "day-sunny", - 2: "night-alt-cloudy", - 3: "day-cloudy", - 5: "fog", - 6: "fog", - 7: "cloudy", - 8: "cloud", - 9: "night-sprinkle", - 10: "day-sprinkle", - 11: "raindrops", - 12: "sprinkle", - 13: "night-alt-showers", - 14: "day-showers", - 15: "rain", - 16: "night-alt-sleet", - 17: "day-sleet", - 18: "sleet", - 19: "night-alt-hail", - 20: "day-hail", - 21: "hail", - 22: "night-alt-snow", - 23: "day-snow", - 24: "snow", - 25: "night-alt-snow", - 26: "day-snow", - 27: "snow", - 28: "night-alt-thunderstorm", - 29: "day-thunderstorm", - 30: "thunderstorm" - }; - - return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; - }, - - /** - * Generates an url with api parameters based on the config. - * @param {string} forecastType daily or 3hourly forecast - * @returns {string} url - */ - getParams (forecastType) { - let params = "?"; - params += `res=${forecastType}`; - params += `&key=${this.config.apiKey}`; - return params; - } -});