|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- /* Magic Mirror
- * Module: MMM-DynamicWeather
- *
- * By Scott Lewis - https://github.com/scottcl88/MMM-DynamicWeather
- * MIT Licensed.
- *
- * A heavily configurable MagicMirror Module to display different animations based on current weather and show customized event effects.
- */
- declare var Log: Console;
- declare var Module: any;
- class Effect {
- constructor() {}
- id: number; //an id made up to use for sequential logic
- month: number;
- day: number;
- year: number = 0;
- images: string[];
- direction: string;
- size: number;
- particleCount: number;
- speedMax: number;
- speedMin: number;
- weatherCode: number;
- weatherCodeMin: number;
- weatherCodeMax: number;
- holiday: string;
- recurrence: string; //monthly, weekly, weekdays, weekends
- doDisplay: boolean = false;
-
- public getYear(): number {
- return this.year ? this.year : 0;
- }
- public getMonth(): number {
- return this.month ? this.month : 0;
- }
- public getDay(): number {
- return this.day ? this.day : 0;
- }
- public getSize(): number {
- return this.size ? this.size : 1;
- }
- public getParticleCount(): number {
- return this.particleCount ? this.particleCount : -1;
- }
- public getSpeedMax(): number {
- return this.speedMax ? this.speedMax : 100;
- }
- public getSpeedMin(): number {
- return this.speedMin ? this.speedMin : 50;
- }
- public getWeatherCode(): number {
- return this.weatherCode ? this.weatherCode : -99;
- }
- public getMinWeatherCode(): number {
- return this.weatherCodeMin ? this.weatherCodeMin : 99999;
- }
- public getMaxWeatherCode(): number {
- return this.weatherCodeMax ? this.weatherCodeMax : -99999;
- }
- public hasWeatherCode(): boolean {
- return (this.weatherCode && this.weatherCode > 0) || (this.weatherCodeMin && this.weatherCodeMin > 0) || (this.weatherCodeMax && this.weatherCodeMax > 0) ? true : false;
- }
- public hasHoliday(): boolean {
- return this.holiday && this.holiday.length > 0 ? true : false;
- }
- public clone(other: Effect) {
- this.id = other.id;
- this.day = other.day;
- this.month = other.month;
- this.year = other.year;
- this.images = other.images;
- this.direction = other.direction;
- this.size = other.size;
- this.particleCount = other.particleCount;
- this.speedMax = other.speedMax;
- this.speedMin = other.speedMin;
- this.weatherCode = other.weatherCode;
- this.weatherCodeMin = other.weatherCodeMin;
- this.weatherCodeMax = other.weatherCodeMax;
- this.holiday = other.holiday;
- this.recurrence = other.recurrence;
- this.doDisplay = other.doDisplay;
- }
- }
- Module.register("MMM-DynamicWeather", {
- defaults: {
- particleCount: 100,
- api_key: "",
- locationID: 0,
- lat: 0,
- lon: 0,
- weatherInterval: 600000, // Every 10 minutes,
- alwaysDisplay: "",
- zIndex: 99,
- opacity: 1,
- fadeDuration: 3000,
- effectDuration: 120000,
- effectDelay: 60000,
- realisticClouds: false,
- hideSun: false,
- hideSnow: false,
- hideSnowman: true,
- hideRain: false,
- hideFlower: true,
- hideClouds: false,
- hideFog: false,
- hideLightning: false,
- lightning1Count: 2,
- lightning2Count: 3,
- sequential: "",
- sunImage: "sun_right",
- effects: [] as Effect[],
- },
-
- start: function () {
- Log.info("Starting MMM-DynamicWeather");
- this.now = new Date();
- this.initialized = false;
- this.weatherLoaded = false;
- this.holidayLoaded = false;
- this.doShowEffects = true;
- this.hasDateEffectsToDisplay = false;
- this.hasHolidayEffectsToDisplay = false;
- this.hasWeatherEffectsToDisplay = true;
- this.effectDurationTimeout = null;
- this.effectDelayTimeout = null;
- this.weatherTimeout = null;
- this.holidayTimeout = null;
- this.allEffects = [] as Effect[];
- this.url = "https://api.openweathermap.org/data/2.5/weather?appid=" + this.config.api_key;
-
- if (this.config.lat && this.config.lon) {
- this.url += "&lat=" + this.config.lat + "&lon=" + this.config.lon;
- }
-
- if (this.config.locationID) {
- this.url += "&id=" + this.config.locationID;
- }
-
- this.snowEffect = new Effect();
- this.snowEffect.images = ["snow1.png", "snow2.png", "snow3.png"];
- this.snowEffect.size = 1;
- this.snowEffect.direction = "down";
-
- (this.realisticCloudsEffect as Effect) = new Effect();
- (this.realisticCloudsEffect as Effect).size = 15;
- (this.realisticCloudsEffect as Effect).direction = "left-right";
- (this.realisticCloudsEffect as Effect).images = ["cloud1.png", "cloud2.png"];
-
- this.weatherCode = 0;
-
- this.allHolidays = [] as string[];
-
- let count = 0;
- this.config.effects.forEach((configEffect) => {
- var effect = new Effect();
- effect.clone(configEffect);
- effect.id = count;
- count++;
- this.allEffects.push(effect);
- this.allHolidays.push(effect.holiday);
- });
-
- this.lastSequentialId = -1;
- if (this.config.sequential) {
- if (this.config.sequential == "effect" || this.config.sequential == "effect-one") {
- this.lastSequential = "weather";
- } else if (this.config.sequential == "weather") {
- this.lastSequential = "effect";
- } else {
- this.lastSequential = "";
- }
- } else {
- this.lastSequential = "";
- }
-
- this.checkDates();
-
- if (this.allHolidays.length > 0) {
- this.getHolidays(this);
- } else {
- this.holidayLoaded = true;
- }
-
- if (!this.config.alwaysDisplay) {
- this.getWeather(this);
- } else {
- this.weatherLoaded = true;
- }
- Log.info("[MMM-DynamicWeather] Finished initialization");
- },
-
- getStyles: function () {
- return ["MMM-DynamicWeather.css"];
- },
-
- checkDates: function () {
- try {
- (this.allEffects as Effect[]).forEach((effect) => {
- var effectMonth = effect.month - 1;
- if (!effect.hasWeatherCode() && !effect.hasHoliday()) {
- //if there is weatherCode or holiday, dates are ignored
- if (effect.getMonth() == 0 && effect.getDay() == 0 && effect.getYear() == 0) {
- //if no weatherCode, no holiday and no dates, then always display it
- if (effect.recurrence == "weekdays") {
- //if its not Sunday (0) and not Saturday (6)
- if (this.now.getDay() !== 6 && this.now.getDay() !== 0) {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- } else if (effect.recurrence == "weekends") {
- //if its Sunday (0) or Saturday (6)
- if (this.now.getDay() == 6 || this.now.getDay() == 0) {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- } else {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- } else {
- //if the month and date match or the month, date and year match
- if (this.now.getMonth() == effectMonth && this.now.getDate() == effect.day) {
- if (effect.getYear() == 0 || this.now.getFullYear() == effect.getYear()) {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- } else if (effect.recurrence == "monthly") {
- //ignore everything but the day
- if (this.now.getDate() == effect.getDay()) {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- } else if (effect.recurrence == "weekly") {
- var effectDay = new Date(effect.getYear(), effectMonth, effect.getDay());
- if (this.now.getDay() == effectDay.getDay()) {
- this.hasDateEffectsToDisplay = true;
- effect.doDisplay = true;
- }
- }
- }
- }
- });
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in checkDates: ", error);
- }
- },
-
- getDom: function () {
- var wrapper = document.createElement("div");
- wrapper.style.zIndex = this.config.zIndex;
- wrapper.style.opacity = this.config.opacity;
- wrapper.className = "wrapper";
- try {
- //setup the fade-out animation
- var fadeDuration = parseInt(this.config.fadeDuration);
- var animationDelay = parseInt(this.config.effectDuration) - fadeDuration;
- var fadeCSS = document.createElement("style");
- fadeCSS.innerHTML = ".fade-out {animation-name: fade; animation-duration: " + fadeDuration + "ms; animation-delay: " + animationDelay + "ms;}";
- wrapper.prepend(fadeCSS);
-
- wrapper.onanimationend = (e) => {
- //delay finished, elements faded out, now remove
- var thisAnimation = e.animationName;
- if (thisAnimation == "fade") {
- wrapper.remove();
- }
- };
-
- if (this.config.alwaysDisplay) {
- switch (this.config.alwaysDisplay) {
- case "snow": {
- this.showCustomEffect(wrapper, this.snowEffect);
- if (this.config.hideSnowman === false || this.config.hideSnowman === "false") {
- this.buildSnowman(wrapper);
- }
- break;
- }
- case "sun": {
- this.makeItSunny(wrapper);
- break;
- }
- case "rain": {
- this.makeItRain(wrapper);
- if (this.config.hideFlower === false || this.config.hideFlower === "false") {
- this.buildFlower(wrapper);
- }
- break;
- }
- case "lightning": {
- this.makeItLightning(wrapper);
- break;
- }
- case "rain-lightning": {
- this.makeItRain(wrapper);
- this.makeItLightning(wrapper);
- break;
- }
- case "cloudy": {
- if (this.config.realisticClouds) {
- this.showCustomEffect(wrapper, this.realisticCloudsEffect);
- } else {
- this.makeItCloudy(wrapper);
- }
- break;
- }
- case "fog": {
- this.makeItFoggy(wrapper);
- break;
- }
- default: {
- console.error("[MMM-DynamicWeather] Invalid config option 'alwaysDisplay'");
- }
- }
- return wrapper;
- }
-
- if (!this.weatherLoaded || !this.holidayLoaded) return wrapper; //need to wait for the weather to first be loaded
-
- if (!this.doShowEffects) return wrapper;
-
- wrapper.className = "wrapper fade-out";
-
- let showEffects = false;
- let showWeather = false;
-
- //check to see what should be shown based on availability and sequential
- if (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay || this.hasWeatherEffectsToDisplay) {
- if (this.lastSequential == "effect" && this.hasWeatherEffectsToDisplay) {
- //if its weather's turn and there are weather to show
- showWeather = true;
- this.lastSequential = "weather";
- } else if (this.lastSequential == "weather" && (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay)) {
- //if its effect's turn and there are effects to show
- showEffects = true;
- this.lastSequential = "effect";
- } else {
- showWeather = true;
- showEffects = true;
- }
- }
-
- if (showEffects) {
- for (let effect of this.allEffects as Effect[]) {
- if (effect.doDisplay) {
- //we can display this effect
- if (this.config.sequential == "effect-one") {
- //only show one effect at a time. if it wasn't the last one and its next in line, then do show it
- if (this.lastSequentialId < effect.id) {
- this.lastSequentialId = effect.id;
- if (this.allEffects.length - 1 == this.lastSequentialId) {
- //reached end of effects, reset
- this.lastSequentialId = -1;
- }
- this.showCustomEffect(wrapper, effect);
- break;
- }
- } else {
- this.showCustomEffect(wrapper, effect);
- }
- }
- }
- }
-
- if (showWeather) {
- //Codes from https://openweathermap.org/weather-conditions
- if (this.weatherCode >= 600 && this.weatherCode <= 622 && !this.config.hideSnow) {
- this.showCustomEffect(wrapper, this.snowEffect);
- if (this.config.hideSnowman === false || this.config.hideSnowman === "false") {
- this.buildSnowman(wrapper);
- }
- if (this.weatherCode >= 611 && this.weatherCode <= 622 && !this.config.hideRain) {
- //snow/rain mix
- this.makeItRain(wrapper);
- }
- } else if (this.weatherCode >= 200 && this.weatherCode <= 531 && !this.config.hideRain) {
- this.makeItRain(wrapper);
- if (this.config.hideFlower === false || this.config.hideFlower === "false") {
- this.buildFlower(wrapper);
- }
- if (this.weatherCode >= 200 && this.weatherCode <= 232 && !this.config.hideLightning) {
- this.makeItLightning(wrapper);
- }
- } else if (this.weatherCode >= 801 && this.weatherCode <= 804 && !this.config.hideClouds) {
- if (this.config.realisticClouds) {
- if (this.weatherCode == 801) {
- (this.realisticCloudsEffect as Effect).size = 8;
- (this.realisticCloudsEffect as Effect).particleCount = 30;
- (this.realisticCloudsEffect as Effect).images = ["cloud1.png"];
- } else if (this.weatherCode == 802) {
- (this.realisticCloudsEffect as Effect).size = 8;
- (this.realisticCloudsEffect as Effect).particleCount = 50;
- (this.realisticCloudsEffect as Effect).images = ["cloud1.png", "cloud2.png"];
- } else if (this.weatherCode == 803) {
- (this.realisticCloudsEffect as Effect).size = 15;
- (this.realisticCloudsEffect as Effect).particleCount = 30;
- (this.realisticCloudsEffect as Effect).images = ["cloud1.png", "cloud2.png"];
- } else if (this.weatherCode == 804) {
- (this.realisticCloudsEffect as Effect).size = 15;
- (this.realisticCloudsEffect as Effect).particleCount = 30;
- (this.realisticCloudsEffect as Effect).images = ["cloud3.png", "cloud2.png", "cloud1.png"];
- }
- this.showCustomEffect(wrapper, this.realisticCloudsEffect);
- } else {
- this.makeItCloudy(wrapper);
- }
- } else if (this.weatherCode >= 701 && this.weatherCode <= 781 && !this.config.hideFog) {
- this.makeItFoggy(wrapper);
- }else if (this.weatherCode == 800 && !this.config.hideSun) {
- this.makeItSunny(wrapper);
- }
- }
-
- console.info("[MMM-DynamicWeather] Displaying effects for: ", this.config.effectDuration);
- this.effectDurationTimeout = setTimeout(this.stopEffect, this.config.effectDuration, this);
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in getDom: ", error);
- }
- return wrapper;
- },
-
- showCustomEffect: function (wrapper: HTMLDivElement, effect: Effect) {
- this.doShowEffects = false;
- var flake, jiggle, size;
-
- var particleCount = effect.getParticleCount();
- if (particleCount < 0) {
- particleCount = this.config.particleCount;
- }
-
- for (var i = 0; i < particleCount; i++) {
- size = effect.getSize(); // * (Math.random() * 0.75) + 0.25;
- let flakeImage = document.createElement("div");
-
- let maxNum = effect.images.length;
- var picIndex = Math.floor(Math.random() * (maxNum - 0) + 0);
- flakeImage.style.backgroundImage = "url('./modules/MMM-DynamicWeather/images/" + effect.images[picIndex] + "')";
- flakeImage.style.transform = "scale(" + size + ", " + size + ")";
- flakeImage.style.opacity = size;
-
- flake = document.createElement("div");
- var animationName;
-
- switch (effect.direction) {
- case "down": {
- flake.className = "flake-downwards";
- flake.style.left = Math.random() * 100 - 10 + "%";
- animationName = "flake-jiggle";
- break;
- }
- case "left-right": {
- flake.className = "flake-left-right";
- flake.style.left = -75 - size * 2 + "px";
- flake.style.top = Math.random() * 100 - 10 + "%";
- flake.style.animationName = "flake-jiggle-left-right";
- break;
- }
- case "right-left": {
- flake.className = "flake-right-left";
- flake.style.right = 75 + size * 2 + "px";
- flake.style.top = Math.random() * 100 - 10 + "%";
- flake.style.animationName = "flake-jiggle-right-left";
- break;
- }
- default: {
- flake.className = "flake-upwards";
- flake.style.left = Math.random() * 100 - 10 + "%";
- animationName = "flake-jiggle";
- break;
- }
- }
-
- let max = effect.getSpeedMax();
- let min = effect.getSpeedMin();
-
- jiggle = document.createElement("div");
- jiggle.style.animationDelay = Math.random() * max + "s";
- jiggle.style.animationDuration = max - Math.random() * min * size + "s";
- if (animationName) {
- jiggle.style.animationName = animationName;
- }
-
- jiggle.appendChild(flakeImage);
-
- size = Math.random() * 0.75 + 0.25;
- jiggle.style.transform = "scale(" + size + ", " + size + ")";
- jiggle.style.opacity = size;
- if (animationName) {
- jiggle.style.animationName = animationName;
- }
-
- flake.appendChild(jiggle);
-
- flake.style.animationDelay = Math.random() * max + "s";
- flake.style.animationDuration = max - Math.random() * min * size + "s";
-
- wrapper.appendChild(flake);
- }
- },
-
- buildSnowman: function (wrapper) {
- this.doShowEffects = false;
-
- var snowmanImage = document.createElement("div");
- snowmanImage.classList.add("snowman");
- snowmanImage.style.animationDuration = this.config.effectDuration - 10000 + "ms"; //subtract for 10s delay
-
- wrapper.appendChild(snowmanImage);
- },
-
- makeItRain: function (wrapper) {
- this.doShowEffects = false;
- var increment = 0;
- while (increment < this.config.particleCount) {
- var randoHundo = Math.floor(Math.random() * (98 - 1 + 1) + 1); //random number between 98 and 1
- var randoFiver = Math.floor(Math.random() * (5 - 2 + 1) + 2);
-
- increment += randoFiver;
-
- let frontDrop = document.createElement("div");
- frontDrop.classList.add("drop");
- frontDrop.style.left = increment + "%";
- frontDrop.style.bottom = randoFiver + randoFiver - 1 + 100 + "%";
- frontDrop.style.animationDelay = "1." + randoHundo + "s";
- frontDrop.style.animationDuration = "1.5" + randoHundo + "s";
-
- let frontStem = document.createElement("div");
- frontStem.classList.add("stem");
- frontStem.style.animationDelay = "1." + randoHundo + "s";
- frontStem.style.animationDuration = "1.5" + randoHundo + "s";
- frontDrop.appendChild(frontStem);
-
- let backDrop = document.createElement("div");
- backDrop.classList.add("drop");
- backDrop.style.opacity = "0.5";
- backDrop.style.right = increment + "%";
- backDrop.style.bottom = randoFiver + randoFiver - 1 + 100 + "%";
- backDrop.style.animationDelay = "1." + randoHundo + "s";
- backDrop.style.animationDuration = "1.5" + randoHundo + "s";
-
- let backStem = document.createElement("div");
- backStem.classList.add("stem");
- backStem.style.animationDelay = "1." + randoHundo + "s";
- backStem.style.animationDuration = "1.5" + randoHundo + "s";
- backDrop.appendChild(backStem);
-
- wrapper.appendChild(backDrop);
- wrapper.appendChild(frontDrop);
- }
- },
-
- buildFlower: function (wrapper) {
- this.doShowEffects = false;
-
- var flowerImage = document.createElement("div");
- flowerImage.classList.add("flower");
- flowerImage.style.animationDuration = this.config.effectDuration - 10000 + "ms"; //subtract for 10s delay
-
- wrapper.appendChild(flowerImage);
- },
-
- makeItLightning: function (wrapper) {
- this.doShowEffects = false;
-
- var lightningImage1 = document.createElement("div");
- lightningImage1.classList.add("lightning1");
- lightningImage1.style.animationIterationCount = this.config.lightning1Count;
-
- var lightningImage2 = document.createElement("div");
- lightningImage2.classList.add("lightning2");
- lightningImage2.style.animationIterationCount = this.config.lightning2Count;
-
- let lightningPlayer = document.createElement("div");
- lightningPlayer.classList.add("lightningPlayer");
- lightningPlayer.appendChild(lightningImage1);
- lightningPlayer.appendChild(lightningImage2);
-
- wrapper.appendChild(lightningPlayer);
- },
-
- makeItSunny: function (wrapper) {
- this.doShowEffects = false;
-
- var sunImage = document.createElement("div");
- sunImage.classList.add("sun");
- sunImage.style.background = "url('./modules/MMM-DynamicWeather/images/" + this.config.sunImage + ".png') center center/cover no-repeat transparent";
-
- let sunPlayer = document.createElement("div");
- sunPlayer.classList.add("sunPlayer");
- sunPlayer.appendChild(sunImage);
-
- wrapper.appendChild(sunPlayer);
- },
-
- makeItCloudy: function (wrapper) {
- this.doShowEffects = false;
- var increment = 0;
- while (increment < this.config.particleCount) {
- var randNum = Math.floor(Math.random() * (25 - 5 + 1) + 5); //random number between 25 and 5
- var speed = Math.floor(Math.random() * (35 - 15 + 1) + 15);
- var size = Math.floor(Math.random() * (60 - 3 + 1) + 3);
-
- increment += randNum;
-
- let cloudBase = document.createElement("div");
- cloudBase.style.animation = "animateCloud " + speed + "s linear infinite";
- cloudBase.style.transform = "scale(0." + size + ")";
-
- let cloud = document.createElement("div");
- cloud.classList.add("cloud");
- cloudBase.appendChild(cloud);
-
- wrapper.appendChild(cloudBase);
- }
- },
-
- makeItFoggy: function (wrapper) {
- this.doShowEffects = false;
-
- var fogImage1 = document.createElement("div");
- fogImage1.classList.add("image01");
-
- var fogImage2 = document.createElement("div");
- fogImage2.classList.add("image02");
-
- let fogPlayer1 = document.createElement("div");
- fogPlayer1.id = "foglayer_01";
- fogPlayer1.classList.add("fog");
- fogPlayer1.appendChild(fogImage1);
- fogPlayer1.appendChild(fogImage2);
-
- wrapper.appendChild(fogPlayer1);
-
- fogImage1 = document.createElement("div");
- fogImage1.classList.add("image01");
-
- fogImage2 = document.createElement("div");
- fogImage2.classList.add("image02");
-
- let fogPlayer2 = document.createElement("div");
- fogPlayer2.id = "foglayer_02";
- fogPlayer2.classList.add("fog");
- fogPlayer2.appendChild(fogImage1);
- fogPlayer2.appendChild(fogImage2);
-
- wrapper.appendChild(fogPlayer2);
-
- fogImage1 = document.createElement("div");
- fogImage1.classList.add("image01");
-
- fogImage2 = document.createElement("div");
- fogImage2.classList.add("image02");
-
- let fogPlayer3 = document.createElement("div");
- fogPlayer3.id = "foglayer_03";
- fogPlayer3.classList.add("fog");
- fogPlayer3.appendChild(fogImage1);
- fogPlayer3.appendChild(fogImage2);
-
- wrapper.appendChild(fogPlayer3);
- },
-
- stopEffect: function (_this) {
- try {
- //wait for delay and reset
- _this.updateDom();
- let delay = _this.config.effectDelay;
- _this.effectDelayTimeout = setTimeout(
- (_that, _effect) => {
- _that.doShowEffects = true;
- _that.updateDom();
- },
- delay,
- _this
- );
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in stopping effects: ", error);
- }
- },
-
- getWeather: function (_this) {
- _this.sendSocketNotification("API-Fetch", _this.url);
- _this.weatherTimeout = setTimeout(_this.getWeather, _this.config.weatherInterval, _this);
- },
- getHolidays: function (_this) {
- try {
- _this.sendSocketNotification("Holiday-Fetch", {});
- var today = new Date();
- var tomorrow = new Date();
- tomorrow.setDate(today.getDate() + 1);
- tomorrow.setHours(0, 0, 0, 0);
- var msTillMidnight = tomorrow.getTime() - today.getTime();
- console.info("[MMM-DynamicWeather] Holidays have been fetched, waiting till midnight (" + msTillMidnight + " ms) to reset.");
- _this.holidayTimeout = setTimeout(_this.resetHolidays, msTillMidnight, _this);
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in getHolidays: ", error);
- }
- },
- resetHolidays: function (_this) {
- try {
- console.info("[MMM-DynamicWeather] Resetting holidays...");
- //Reset all effects with a holiday to not show, we will trigger another getHolidays to see if the next day has another holiday to display next
- (_this.allEffects as Effect[]).forEach((effect) => {
- if (effect.holiday) {
- effect.doDisplay = false;
- }
- });
- _this.hasHolidayEffectsToDisplay = false;
- _this.updateDom();
- console.info("[MMM-DynamicWeather] Holidays reset.");
- _this.getHolidays(_this);
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in resetting holidays: ", error);
- }
- },
-
- parseHolidays: function (body: string) {
- let today = new Date();
- let todayHolidays = [];
- todayHolidays.push("test");
-
- try {
- var parser = new DOMParser();
- var doc = parser.parseFromString(body, "text/html");
-
- var children = doc.getElementById("holidays-table").children[1].children;
- for (var i = 0; i < children.length; i++) {
- var child1 = children[i];
- if (child1.hasAttribute("data-date")) {
- var holidayDateStr = child1.getAttribute("data-date");
- var child2 = child1.children;
- for (var j = 0; j < child2.length; j++) {
- var child3 = child2[j];
- if (child3.hasChildNodes()) {
- for (var k = 0; k < child3.children.length; k++) {
- var child4 = child3.children[k];
- for (var l = 0; l < this.allHolidays.length; l++) {
- var effectHoliday = this.allHolidays[l];
- if (child4.textContent == effectHoliday) {
- var holidayDate = new Date(parseInt(holidayDateStr));
- if (holidayDate.getUTCDate() == today.getDate() && holidayDate.getUTCMonth() == today.getMonth()) {
- todayHolidays.push(effectHoliday);
- }
- }
- }
- }
- }
- }
- }
- }
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in parsing holidays: ", error);
- }
-
- return todayHolidays;
- },
-
- socketNotificationReceived: function (notification, payload) {
- try {
- if (notification === "API-Received" && payload.url === this.url) {
- this.weatherLoaded = true;
- if (!payload.success) {
- console.error("[MMM-DynamicWeather] API-Receieved failure status");
- return;
- }
- let newCode = payload.result.weather[0].id;
-
- let doUpdate = false;
-
- //check to see if the newCode is different than already displayed, and if so, is it going to show anything
- if (newCode != this.weatherCode) {
- this.weatherCode = newCode;
- if (newCode >= 600 && newCode <= 622 && !this.config.hideSnow) {
- doUpdate = true;
- }
- if ((newCode >= 200 && newCode <= 531) || (newCode >= 611 && newCode <= 622 && !this.config.hideRain)) {
- doUpdate = true;
- }
- if (newCode >= 200 && newCode <= 232 && !this.config.hideLightning) {
- doUpdate = true;
- }
- if (newCode >= 801 && newCode <= 804 && !this.config.hideClouds) {
- doUpdate = true;
- }
- if (newCode >= 701 && newCode <= 781 && !this.config.hideFog) {
- doUpdate = true;
- }
- if (newCode == 800 && !this.config.hideSun) {
- doUpdate = true;
- }
- (this.allEffects as Effect[]).forEach((effect) => {
- if (effect.getWeatherCode() == newCode || (effect.getMinWeatherCode() <= newCode && effect.getMaxWeatherCode() >= newCode)) {
- doUpdate = true;
- effect.doDisplay = true;
- this.hasWeatherEffectsToDisplay = true;
- }
- });
- }
-
- //only update the dom if the weather is different (unless holiday or date effects exist and holiday has finished loading)
- if (doUpdate || (this.holidayLoaded && (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay))) {
- this.doShowEffects = true;
- clearTimeout(this.effectDurationTimeout);
- clearTimeout(this.effectDelayTimeout);
- this.updateDom();
- }
- }
- if (notification === "Holiday-Received") {
- this.holidayLoaded = true;
- if (!payload.success) {
- console.error("[MMM-DynamicWeather] Holiday-Receieved failure status");
- return;
- }
- let doUpdate = false;
- let todayHolidays = [] as string[];
- todayHolidays = this.parseHolidays(payload.result.holidayBody);
-
- //returned a list of holidays for today, check to see if any effects have the same holiday name, if so display them and update dom
- (this.allEffects as Effect[]).forEach((effect) => {
- todayHolidays.forEach((holidayName) => {
- if (effect.holiday == holidayName) {
- doUpdate = true;
- effect.doDisplay = true;
- this.hasHolidayEffectsToDisplay = true;
- }
- });
- });
-
- //only update the dom if the effects have a holiday to show today (unless weather and date effects exist and weather has finished loading)
- if (doUpdate || (this.weatherLoaded && (this.hasDateEffectsToDisplay || this.hasWeatherEffectsToDisplay))) {
- this.doShowEffects = true;
- clearTimeout(this.effectDurationTimeout);
- clearTimeout(this.effectDelayTimeout);
- this.updateDom();
- }
- }
- } catch (error) {
- console.error("[MMM-DynamicWeather] Error occured in notification received: ", error);
- }
- },
- });
|