Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MMM-DynamicWeather.js 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. var Effect = /** @class */ (function () {
  2. function Effect() {
  3. this.year = 0;
  4. this.doDisplay = false;
  5. }
  6. Effect.prototype.getYear = function () {
  7. return this.year ? this.year : 0;
  8. };
  9. Effect.prototype.getMonth = function () {
  10. return this.month ? this.month : 0;
  11. };
  12. Effect.prototype.getDay = function () {
  13. return this.day ? this.day : 0;
  14. };
  15. Effect.prototype.getSize = function () {
  16. return this.size ? this.size : 1;
  17. };
  18. Effect.prototype.getParticleCount = function () {
  19. return this.particleCount ? this.particleCount : -1;
  20. };
  21. Effect.prototype.getSpeedMax = function () {
  22. return this.speedMax ? this.speedMax : 100;
  23. };
  24. Effect.prototype.getSpeedMin = function () {
  25. return this.speedMin ? this.speedMin : 50;
  26. };
  27. Effect.prototype.getWeatherCode = function () {
  28. return this.weatherCode ? this.weatherCode : -99;
  29. };
  30. Effect.prototype.getMinWeatherCode = function () {
  31. return this.weatherCodeMin ? this.weatherCodeMin : 99999;
  32. };
  33. Effect.prototype.getMaxWeatherCode = function () {
  34. return this.weatherCodeMax ? this.weatherCodeMax : -99999;
  35. };
  36. Effect.prototype.hasWeatherCode = function () {
  37. return (this.weatherCode && this.weatherCode > 0) || (this.weatherCodeMin && this.weatherCodeMin > 0) || (this.weatherCodeMax && this.weatherCodeMax > 0) ? true : false;
  38. };
  39. Effect.prototype.hasHoliday = function () {
  40. return this.holiday && this.holiday.length > 0 ? true : false;
  41. };
  42. Effect.prototype.clone = function (other) {
  43. this.id = other.id;
  44. this.day = other.day;
  45. this.month = other.month;
  46. this.year = other.year;
  47. this.images = other.images;
  48. this.direction = other.direction;
  49. this.size = other.size;
  50. this.particleCount = other.particleCount;
  51. this.speedMax = other.speedMax;
  52. this.speedMin = other.speedMin;
  53. this.weatherCode = other.weatherCode;
  54. this.weatherCodeMin = other.weatherCodeMin;
  55. this.weatherCodeMax = other.weatherCodeMax;
  56. this.holiday = other.holiday;
  57. this.recurrence = other.recurrence;
  58. this.doDisplay = other.doDisplay;
  59. };
  60. return Effect;
  61. }());
  62. Module.register("MMM-DynamicWeather", {
  63. defaults: {
  64. particleCount: 100,
  65. api_key: "",
  66. locationID: 0,
  67. lat: 0,
  68. lon: 0,
  69. weatherInterval: 600000,
  70. alwaysDisplay: "",
  71. zIndex: 99,
  72. opacity: 1,
  73. fadeDuration: 3000,
  74. effectDuration: 120000,
  75. effectDelay: 60000,
  76. realisticClouds: false,
  77. hideSun: false,
  78. hideSnow: false,
  79. hideSnowman: true,
  80. hideRain: false,
  81. hideFlower: true,
  82. hideClouds: false,
  83. hideFog: false,
  84. hideLightning: false,
  85. lightning1Count: 2,
  86. lightning2Count: 3,
  87. sequential: "",
  88. sunImage: "sun_right",
  89. effects: [],
  90. },
  91. start: function () {
  92. var _this_1 = this;
  93. Log.info("Starting MMM-DynamicWeather");
  94. this.now = new Date();
  95. this.initialized = false;
  96. this.weatherLoaded = false;
  97. this.holidayLoaded = false;
  98. this.doShowEffects = true;
  99. this.hasDateEffectsToDisplay = false;
  100. this.hasHolidayEffectsToDisplay = false;
  101. this.hasWeatherEffectsToDisplay = true;
  102. this.effectDurationTimeout = null;
  103. this.effectDelayTimeout = null;
  104. this.weatherTimeout = null;
  105. this.holidayTimeout = null;
  106. this.allEffects = [];
  107. this.url = "https://api.openweathermap.org/data/2.5/weather?appid=" + this.config.api_key;
  108. if (this.config.lat && this.config.lon) {
  109. this.url += "&lat=" + this.config.lat + "&lon=" + this.config.lon;
  110. }
  111. if (this.config.locationID) {
  112. this.url += "&id=" + this.config.locationID;
  113. }
  114. this.snowEffect = new Effect();
  115. this.snowEffect.images = ["snow1.png", "snow2.png", "snow3.png"];
  116. this.snowEffect.size = 1;
  117. this.snowEffect.direction = "down";
  118. this.realisticCloudsEffect = new Effect();
  119. this.realisticCloudsEffect.size = 15;
  120. this.realisticCloudsEffect.direction = "left-right";
  121. this.realisticCloudsEffect.images = ["cloud1.png", "cloud2.png"];
  122. this.weatherCode = 0;
  123. this.allHolidays = [];
  124. var count = 0;
  125. this.config.effects.forEach(function (configEffect) {
  126. var effect = new Effect();
  127. effect.clone(configEffect);
  128. effect.id = count;
  129. count++;
  130. _this_1.allEffects.push(effect);
  131. _this_1.allHolidays.push(effect.holiday);
  132. });
  133. this.lastSequentialId = -1;
  134. if (this.config.sequential) {
  135. if (this.config.sequential == "effect" || this.config.sequential == "effect-one") {
  136. this.lastSequential = "weather";
  137. }
  138. else if (this.config.sequential == "weather") {
  139. this.lastSequential = "effect";
  140. }
  141. else {
  142. this.lastSequential = "";
  143. }
  144. }
  145. else {
  146. this.lastSequential = "";
  147. }
  148. this.checkDates();
  149. if (this.allHolidays.length > 0) {
  150. this.getHolidays(this);
  151. }
  152. else {
  153. this.holidayLoaded = true;
  154. }
  155. if (!this.config.alwaysDisplay) {
  156. this.getWeather(this);
  157. }
  158. else {
  159. this.weatherLoaded = true;
  160. }
  161. Log.info("[MMM-DynamicWeather] Finished initialization");
  162. },
  163. getStyles: function () {
  164. return ["MMM-DynamicWeather.css"];
  165. },
  166. checkDates: function () {
  167. var _this_1 = this;
  168. try {
  169. this.allEffects.forEach(function (effect) {
  170. var effectMonth = effect.month - 1;
  171. if (!effect.hasWeatherCode() && !effect.hasHoliday()) {
  172. //if there is weatherCode or holiday, dates are ignored
  173. if (effect.getMonth() == 0 && effect.getDay() == 0 && effect.getYear() == 0) {
  174. //if no weatherCode, no holiday and no dates, then always display it
  175. if (effect.recurrence == "weekdays") {
  176. //if its not Sunday (0) and not Saturday (6)
  177. if (_this_1.now.getDay() !== 6 && _this_1.now.getDay() !== 0) {
  178. _this_1.hasDateEffectsToDisplay = true;
  179. effect.doDisplay = true;
  180. }
  181. }
  182. else if (effect.recurrence == "weekends") {
  183. //if its Sunday (0) or Saturday (6)
  184. if (_this_1.now.getDay() == 6 || _this_1.now.getDay() == 0) {
  185. _this_1.hasDateEffectsToDisplay = true;
  186. effect.doDisplay = true;
  187. }
  188. }
  189. else {
  190. _this_1.hasDateEffectsToDisplay = true;
  191. effect.doDisplay = true;
  192. }
  193. }
  194. else {
  195. //if the month and date match or the month, date and year match
  196. if (_this_1.now.getMonth() == effectMonth && _this_1.now.getDate() == effect.day) {
  197. if (effect.getYear() == 0 || _this_1.now.getFullYear() == effect.getYear()) {
  198. _this_1.hasDateEffectsToDisplay = true;
  199. effect.doDisplay = true;
  200. }
  201. }
  202. else if (effect.recurrence == "monthly") {
  203. //ignore everything but the day
  204. if (_this_1.now.getDate() == effect.getDay()) {
  205. _this_1.hasDateEffectsToDisplay = true;
  206. effect.doDisplay = true;
  207. }
  208. }
  209. else if (effect.recurrence == "weekly") {
  210. var effectDay = new Date(effect.getYear(), effectMonth, effect.getDay());
  211. if (_this_1.now.getDay() == effectDay.getDay()) {
  212. _this_1.hasDateEffectsToDisplay = true;
  213. effect.doDisplay = true;
  214. }
  215. }
  216. }
  217. }
  218. });
  219. }
  220. catch (error) {
  221. console.error("[MMM-DynamicWeather] Error occured in checkDates: ", error);
  222. }
  223. },
  224. getDom: function () {
  225. var wrapper = document.createElement("div");
  226. wrapper.style.zIndex = this.config.zIndex;
  227. wrapper.style.opacity = this.config.opacity;
  228. wrapper.className = "wrapper";
  229. try {
  230. //setup the fade-out animation
  231. var fadeDuration = parseInt(this.config.fadeDuration);
  232. var animationDelay = parseInt(this.config.effectDuration) - fadeDuration;
  233. var fadeCSS = document.createElement("style");
  234. fadeCSS.innerHTML = ".fade-out {animation-name: fade; animation-duration: " + fadeDuration + "ms; animation-delay: " + animationDelay + "ms;}";
  235. wrapper.prepend(fadeCSS);
  236. wrapper.onanimationend = function (e) {
  237. //delay finished, elements faded out, now remove
  238. var thisAnimation = e.animationName;
  239. if (thisAnimation == "fade") {
  240. wrapper.remove();
  241. }
  242. };
  243. if (this.config.alwaysDisplay) {
  244. switch (this.config.alwaysDisplay) {
  245. case "snow": {
  246. this.showCustomEffect(wrapper, this.snowEffect);
  247. if (this.config.hideSnowman === false || this.config.hideSnowman === "false") {
  248. this.buildSnowman(wrapper);
  249. }
  250. break;
  251. }
  252. case "sun": {
  253. this.makeItSunny(wrapper);
  254. break;
  255. }
  256. case "rain": {
  257. this.makeItRain(wrapper);
  258. if (this.config.hideFlower === false || this.config.hideFlower === "false") {
  259. this.buildFlower(wrapper);
  260. }
  261. break;
  262. }
  263. case "lightning": {
  264. this.makeItLightning(wrapper);
  265. break;
  266. }
  267. case "rain-lightning": {
  268. this.makeItRain(wrapper);
  269. this.makeItLightning(wrapper);
  270. break;
  271. }
  272. case "cloudy": {
  273. if (this.config.realisticClouds) {
  274. this.showCustomEffect(wrapper, this.realisticCloudsEffect);
  275. }
  276. else {
  277. this.makeItCloudy(wrapper);
  278. }
  279. break;
  280. }
  281. case "fog": {
  282. this.makeItFoggy(wrapper);
  283. break;
  284. }
  285. default: {
  286. console.error("[MMM-DynamicWeather] Invalid config option 'alwaysDisplay'");
  287. }
  288. }
  289. return wrapper;
  290. }
  291. if (!this.weatherLoaded || !this.holidayLoaded)
  292. return wrapper; //need to wait for the weather to first be loaded
  293. if (!this.doShowEffects)
  294. return wrapper;
  295. wrapper.className = "wrapper fade-out";
  296. var showEffects = false;
  297. var showWeather = false;
  298. //check to see what should be shown based on availability and sequential
  299. if (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay || this.hasWeatherEffectsToDisplay) {
  300. if (this.lastSequential == "effect" && this.hasWeatherEffectsToDisplay) {
  301. //if its weather's turn and there are weather to show
  302. showWeather = true;
  303. this.lastSequential = "weather";
  304. }
  305. else if (this.lastSequential == "weather" && (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay)) {
  306. //if its effect's turn and there are effects to show
  307. showEffects = true;
  308. this.lastSequential = "effect";
  309. }
  310. else {
  311. showWeather = true;
  312. showEffects = true;
  313. }
  314. }
  315. if (showEffects) {
  316. for (var _i = 0, _a = this.allEffects; _i < _a.length; _i++) {
  317. var effect = _a[_i];
  318. if (effect.doDisplay) {
  319. //we can display this effect
  320. if (this.config.sequential == "effect-one") {
  321. //only show one effect at a time. if it wasn't the last one and its next in line, then do show it
  322. if (this.lastSequentialId < effect.id) {
  323. this.lastSequentialId = effect.id;
  324. if (this.allEffects.length - 1 == this.lastSequentialId) {
  325. //reached end of effects, reset
  326. this.lastSequentialId = -1;
  327. }
  328. this.showCustomEffect(wrapper, effect);
  329. break;
  330. }
  331. }
  332. else {
  333. this.showCustomEffect(wrapper, effect);
  334. }
  335. }
  336. }
  337. }
  338. if (showWeather) {
  339. //Codes from https://openweathermap.org/weather-conditions
  340. if (this.weatherCode >= 600 && this.weatherCode <= 622 && !this.config.hideSnow) {
  341. this.showCustomEffect(wrapper, this.snowEffect);
  342. if (this.config.hideSnowman === false || this.config.hideSnowman === "false") {
  343. this.buildSnowman(wrapper);
  344. }
  345. if (this.weatherCode >= 611 && this.weatherCode <= 622 && !this.config.hideRain) {
  346. //snow/rain mix
  347. this.makeItRain(wrapper);
  348. }
  349. }
  350. else if (this.weatherCode >= 200 && this.weatherCode <= 531 && !this.config.hideRain) {
  351. this.makeItRain(wrapper);
  352. if (this.config.hideFlower === false || this.config.hideFlower === "false") {
  353. this.buildFlower(wrapper);
  354. }
  355. if (this.weatherCode >= 200 && this.weatherCode <= 232 && !this.config.hideLightning) {
  356. this.makeItLightning(wrapper);
  357. }
  358. }
  359. else if (this.weatherCode >= 801 && this.weatherCode <= 804 && !this.config.hideClouds) {
  360. if (this.config.realisticClouds) {
  361. if (this.weatherCode == 801) {
  362. this.realisticCloudsEffect.size = 8;
  363. this.realisticCloudsEffect.particleCount = 30;
  364. this.realisticCloudsEffect.images = ["cloud1.png"];
  365. }
  366. else if (this.weatherCode == 802) {
  367. this.realisticCloudsEffect.size = 8;
  368. this.realisticCloudsEffect.particleCount = 50;
  369. this.realisticCloudsEffect.images = ["cloud1.png", "cloud2.png"];
  370. }
  371. else if (this.weatherCode == 803) {
  372. this.realisticCloudsEffect.size = 15;
  373. this.realisticCloudsEffect.particleCount = 30;
  374. this.realisticCloudsEffect.images = ["cloud1.png", "cloud2.png"];
  375. }
  376. else if (this.weatherCode == 804) {
  377. this.realisticCloudsEffect.size = 15;
  378. this.realisticCloudsEffect.particleCount = 30;
  379. this.realisticCloudsEffect.images = ["cloud3.png", "cloud2.png", "cloud1.png"];
  380. }
  381. this.showCustomEffect(wrapper, this.realisticCloudsEffect);
  382. }
  383. else {
  384. this.makeItCloudy(wrapper);
  385. }
  386. }
  387. else if (this.weatherCode >= 701 && this.weatherCode <= 781 && !this.config.hideFog) {
  388. this.makeItFoggy(wrapper);
  389. }
  390. else if (this.weatherCode == 800 && !this.config.hideSun) {
  391. this.makeItSunny(wrapper);
  392. }
  393. }
  394. console.info("[MMM-DynamicWeather] Displaying effects for: ", this.config.effectDuration);
  395. this.effectDurationTimeout = setTimeout(this.stopEffect, this.config.effectDuration, this);
  396. }
  397. catch (error) {
  398. console.error("[MMM-DynamicWeather] Error occured in getDom: ", error);
  399. }
  400. return wrapper;
  401. },
  402. showCustomEffect: function (wrapper, effect) {
  403. this.doShowEffects = false;
  404. var flake, jiggle, size;
  405. var particleCount = effect.getParticleCount();
  406. if (particleCount < 0) {
  407. particleCount = this.config.particleCount;
  408. }
  409. for (var i = 0; i < particleCount; i++) {
  410. size = effect.getSize(); // * (Math.random() * 0.75) + 0.25;
  411. var flakeImage = document.createElement("div");
  412. var maxNum = effect.images.length;
  413. var picIndex = Math.floor(Math.random() * (maxNum - 0) + 0);
  414. flakeImage.style.backgroundImage = "url('./modules/MMM-DynamicWeather/images/" + effect.images[picIndex] + "')";
  415. flakeImage.style.transform = "scale(" + size + ", " + size + ")";
  416. flakeImage.style.opacity = size;
  417. flake = document.createElement("div");
  418. var animationName;
  419. switch (effect.direction) {
  420. case "down": {
  421. flake.className = "flake-downwards";
  422. flake.style.left = Math.random() * 100 - 10 + "%";
  423. animationName = "flake-jiggle";
  424. break;
  425. }
  426. case "left-right": {
  427. flake.className = "flake-left-right";
  428. flake.style.left = -75 - size * 2 + "px";
  429. flake.style.top = Math.random() * 100 - 10 + "%";
  430. flake.style.animationName = "flake-jiggle-left-right";
  431. break;
  432. }
  433. case "right-left": {
  434. flake.className = "flake-right-left";
  435. flake.style.right = 75 + size * 2 + "px";
  436. flake.style.top = Math.random() * 100 - 10 + "%";
  437. flake.style.animationName = "flake-jiggle-right-left";
  438. break;
  439. }
  440. default: {
  441. flake.className = "flake-upwards";
  442. flake.style.left = Math.random() * 100 - 10 + "%";
  443. animationName = "flake-jiggle";
  444. break;
  445. }
  446. }
  447. var max = effect.getSpeedMax();
  448. var min = effect.getSpeedMin();
  449. jiggle = document.createElement("div");
  450. jiggle.style.animationDelay = Math.random() * max + "s";
  451. jiggle.style.animationDuration = max - Math.random() * min * size + "s";
  452. if (animationName) {
  453. jiggle.style.animationName = animationName;
  454. }
  455. jiggle.appendChild(flakeImage);
  456. size = Math.random() * 0.75 + 0.25;
  457. jiggle.style.transform = "scale(" + size + ", " + size + ")";
  458. jiggle.style.opacity = size;
  459. if (animationName) {
  460. jiggle.style.animationName = animationName;
  461. }
  462. flake.appendChild(jiggle);
  463. flake.style.animationDelay = Math.random() * max + "s";
  464. flake.style.animationDuration = max - Math.random() * min * size + "s";
  465. wrapper.appendChild(flake);
  466. }
  467. },
  468. buildSnowman: function (wrapper) {
  469. this.doShowEffects = false;
  470. var snowmanImage = document.createElement("div");
  471. snowmanImage.classList.add("snowman");
  472. snowmanImage.style.animationDuration = this.config.effectDuration - 10000 + "ms"; //subtract for 10s delay
  473. wrapper.appendChild(snowmanImage);
  474. },
  475. makeItRain: function (wrapper) {
  476. this.doShowEffects = false;
  477. var increment = 0;
  478. while (increment < this.config.particleCount) {
  479. var randoHundo = Math.floor(Math.random() * (98 - 1 + 1) + 1); //random number between 98 and 1
  480. var randoFiver = Math.floor(Math.random() * (5 - 2 + 1) + 2);
  481. increment += randoFiver;
  482. var frontDrop = document.createElement("div");
  483. frontDrop.classList.add("drop");
  484. frontDrop.style.left = increment + "%";
  485. frontDrop.style.bottom = randoFiver + randoFiver - 1 + 100 + "%";
  486. frontDrop.style.animationDelay = "1." + randoHundo + "s";
  487. frontDrop.style.animationDuration = "1.5" + randoHundo + "s";
  488. var frontStem = document.createElement("div");
  489. frontStem.classList.add("stem");
  490. frontStem.style.animationDelay = "1." + randoHundo + "s";
  491. frontStem.style.animationDuration = "1.5" + randoHundo + "s";
  492. frontDrop.appendChild(frontStem);
  493. var backDrop = document.createElement("div");
  494. backDrop.classList.add("drop");
  495. backDrop.style.opacity = "0.5";
  496. backDrop.style.right = increment + "%";
  497. backDrop.style.bottom = randoFiver + randoFiver - 1 + 100 + "%";
  498. backDrop.style.animationDelay = "1." + randoHundo + "s";
  499. backDrop.style.animationDuration = "1.5" + randoHundo + "s";
  500. var backStem = document.createElement("div");
  501. backStem.classList.add("stem");
  502. backStem.style.animationDelay = "1." + randoHundo + "s";
  503. backStem.style.animationDuration = "1.5" + randoHundo + "s";
  504. backDrop.appendChild(backStem);
  505. wrapper.appendChild(backDrop);
  506. wrapper.appendChild(frontDrop);
  507. }
  508. },
  509. buildFlower: function (wrapper) {
  510. this.doShowEffects = false;
  511. var flowerImage = document.createElement("div");
  512. flowerImage.classList.add("flower");
  513. flowerImage.style.animationDuration = this.config.effectDuration - 10000 + "ms"; //subtract for 10s delay
  514. wrapper.appendChild(flowerImage);
  515. },
  516. makeItLightning: function (wrapper) {
  517. this.doShowEffects = false;
  518. var lightningImage1 = document.createElement("div");
  519. lightningImage1.classList.add("lightning1");
  520. lightningImage1.style.animationIterationCount = this.config.lightning1Count;
  521. var lightningImage2 = document.createElement("div");
  522. lightningImage2.classList.add("lightning2");
  523. lightningImage2.style.animationIterationCount = this.config.lightning2Count;
  524. var lightningPlayer = document.createElement("div");
  525. lightningPlayer.classList.add("lightningPlayer");
  526. lightningPlayer.appendChild(lightningImage1);
  527. lightningPlayer.appendChild(lightningImage2);
  528. wrapper.appendChild(lightningPlayer);
  529. },
  530. makeItSunny: function (wrapper) {
  531. this.doShowEffects = false;
  532. var sunImage = document.createElement("div");
  533. sunImage.classList.add("sun");
  534. sunImage.style.background = "url('./modules/MMM-DynamicWeather/images/" + this.config.sunImage + ".png') center center/cover no-repeat transparent";
  535. var sunPlayer = document.createElement("div");
  536. sunPlayer.classList.add("sunPlayer");
  537. sunPlayer.appendChild(sunImage);
  538. wrapper.appendChild(sunPlayer);
  539. },
  540. makeItCloudy: function (wrapper) {
  541. this.doShowEffects = false;
  542. var increment = 0;
  543. while (increment < this.config.particleCount) {
  544. var randNum = Math.floor(Math.random() * (25 - 5 + 1) + 5); //random number between 25 and 5
  545. var speed = Math.floor(Math.random() * (35 - 15 + 1) + 15);
  546. var size = Math.floor(Math.random() * (60 - 3 + 1) + 3);
  547. increment += randNum;
  548. var cloudBase = document.createElement("div");
  549. cloudBase.style.animation = "animateCloud " + speed + "s linear infinite";
  550. cloudBase.style.transform = "scale(0." + size + ")";
  551. var cloud = document.createElement("div");
  552. cloud.classList.add("cloud");
  553. cloudBase.appendChild(cloud);
  554. wrapper.appendChild(cloudBase);
  555. }
  556. },
  557. makeItFoggy: function (wrapper) {
  558. this.doShowEffects = false;
  559. var fogImage1 = document.createElement("div");
  560. fogImage1.classList.add("image01");
  561. var fogImage2 = document.createElement("div");
  562. fogImage2.classList.add("image02");
  563. var fogPlayer1 = document.createElement("div");
  564. fogPlayer1.id = "foglayer_01";
  565. fogPlayer1.classList.add("fog");
  566. fogPlayer1.appendChild(fogImage1);
  567. fogPlayer1.appendChild(fogImage2);
  568. wrapper.appendChild(fogPlayer1);
  569. fogImage1 = document.createElement("div");
  570. fogImage1.classList.add("image01");
  571. fogImage2 = document.createElement("div");
  572. fogImage2.classList.add("image02");
  573. var fogPlayer2 = document.createElement("div");
  574. fogPlayer2.id = "foglayer_02";
  575. fogPlayer2.classList.add("fog");
  576. fogPlayer2.appendChild(fogImage1);
  577. fogPlayer2.appendChild(fogImage2);
  578. wrapper.appendChild(fogPlayer2);
  579. fogImage1 = document.createElement("div");
  580. fogImage1.classList.add("image01");
  581. fogImage2 = document.createElement("div");
  582. fogImage2.classList.add("image02");
  583. var fogPlayer3 = document.createElement("div");
  584. fogPlayer3.id = "foglayer_03";
  585. fogPlayer3.classList.add("fog");
  586. fogPlayer3.appendChild(fogImage1);
  587. fogPlayer3.appendChild(fogImage2);
  588. wrapper.appendChild(fogPlayer3);
  589. },
  590. stopEffect: function (_this) {
  591. try {
  592. //wait for delay and reset
  593. _this.updateDom();
  594. var delay = _this.config.effectDelay;
  595. _this.effectDelayTimeout = setTimeout(function (_that, _effect) {
  596. _that.doShowEffects = true;
  597. _that.updateDom();
  598. }, delay, _this);
  599. }
  600. catch (error) {
  601. console.error("[MMM-DynamicWeather] Error occured in stopping effects: ", error);
  602. }
  603. },
  604. getWeather: function (_this) {
  605. _this.sendSocketNotification("API-Fetch", _this.url);
  606. _this.weatherTimeout = setTimeout(_this.getWeather, _this.config.weatherInterval, _this);
  607. },
  608. getHolidays: function (_this) {
  609. try {
  610. _this.sendSocketNotification("Holiday-Fetch", {});
  611. var today = new Date();
  612. var tomorrow = new Date();
  613. tomorrow.setDate(today.getDate() + 1);
  614. tomorrow.setHours(0, 0, 0, 0);
  615. var msTillMidnight = tomorrow.getTime() - today.getTime();
  616. console.info("[MMM-DynamicWeather] Holidays have been fetched, waiting till midnight (" + msTillMidnight + " ms) to reset.");
  617. _this.holidayTimeout = setTimeout(_this.resetHolidays, msTillMidnight, _this);
  618. }
  619. catch (error) {
  620. console.error("[MMM-DynamicWeather] Error occured in getHolidays: ", error);
  621. }
  622. },
  623. resetHolidays: function (_this) {
  624. try {
  625. console.info("[MMM-DynamicWeather] Resetting holidays...");
  626. //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
  627. _this.allEffects.forEach(function (effect) {
  628. if (effect.holiday) {
  629. effect.doDisplay = false;
  630. }
  631. });
  632. _this.hasHolidayEffectsToDisplay = false;
  633. _this.updateDom();
  634. console.info("[MMM-DynamicWeather] Holidays reset.");
  635. _this.getHolidays(_this);
  636. }
  637. catch (error) {
  638. console.error("[MMM-DynamicWeather] Error occured in resetting holidays: ", error);
  639. }
  640. },
  641. parseHolidays: function (body) {
  642. var today = new Date();
  643. var todayHolidays = [];
  644. todayHolidays.push("test");
  645. try {
  646. var parser = new DOMParser();
  647. var doc = parser.parseFromString(body, "text/html");
  648. var children = doc.getElementById("holidays-table").children[1].children;
  649. for (var i = 0; i < children.length; i++) {
  650. var child1 = children[i];
  651. if (child1.hasAttribute("data-date")) {
  652. var holidayDateStr = child1.getAttribute("data-date");
  653. var child2 = child1.children;
  654. for (var j = 0; j < child2.length; j++) {
  655. var child3 = child2[j];
  656. if (child3.hasChildNodes()) {
  657. for (var k = 0; k < child3.children.length; k++) {
  658. var child4 = child3.children[k];
  659. for (var l = 0; l < this.allHolidays.length; l++) {
  660. var effectHoliday = this.allHolidays[l];
  661. if (child4.textContent == effectHoliday) {
  662. var holidayDate = new Date(parseInt(holidayDateStr));
  663. if (holidayDate.getUTCDate() == today.getDate() && holidayDate.getUTCMonth() == today.getMonth()) {
  664. todayHolidays.push(effectHoliday);
  665. }
  666. }
  667. }
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }
  674. catch (error) {
  675. console.error("[MMM-DynamicWeather] Error occured in parsing holidays: ", error);
  676. }
  677. return todayHolidays;
  678. },
  679. socketNotificationReceived: function (notification, payload) {
  680. var _this_1 = this;
  681. try {
  682. if (notification === "API-Received" && payload.url === this.url) {
  683. this.weatherLoaded = true;
  684. if (!payload.success) {
  685. console.error("[MMM-DynamicWeather] API-Receieved failure status");
  686. return;
  687. }
  688. var newCode_1 = payload.result.weather[0].id;
  689. var doUpdate_1 = false;
  690. //check to see if the newCode is different than already displayed, and if so, is it going to show anything
  691. if (newCode_1 != this.weatherCode) {
  692. this.weatherCode = newCode_1;
  693. if (newCode_1 >= 600 && newCode_1 <= 622 && !this.config.hideSnow) {
  694. doUpdate_1 = true;
  695. }
  696. if ((newCode_1 >= 200 && newCode_1 <= 531) || (newCode_1 >= 611 && newCode_1 <= 622 && !this.config.hideRain)) {
  697. doUpdate_1 = true;
  698. }
  699. if (newCode_1 >= 200 && newCode_1 <= 232 && !this.config.hideLightning) {
  700. doUpdate_1 = true;
  701. }
  702. if (newCode_1 >= 801 && newCode_1 <= 804 && !this.config.hideClouds) {
  703. doUpdate_1 = true;
  704. }
  705. if (newCode_1 >= 701 && newCode_1 <= 781 && !this.config.hideFog) {
  706. doUpdate_1 = true;
  707. }
  708. if (newCode_1 == 800 && !this.config.hideSun) {
  709. doUpdate_1 = true;
  710. }
  711. this.allEffects.forEach(function (effect) {
  712. if (effect.getWeatherCode() == newCode_1 || (effect.getMinWeatherCode() <= newCode_1 && effect.getMaxWeatherCode() >= newCode_1)) {
  713. doUpdate_1 = true;
  714. effect.doDisplay = true;
  715. _this_1.hasWeatherEffectsToDisplay = true;
  716. }
  717. });
  718. }
  719. //only update the dom if the weather is different (unless holiday or date effects exist and holiday has finished loading)
  720. if (doUpdate_1 || (this.holidayLoaded && (this.hasDateEffectsToDisplay || this.hasHolidayEffectsToDisplay))) {
  721. this.doShowEffects = true;
  722. clearTimeout(this.effectDurationTimeout);
  723. clearTimeout(this.effectDelayTimeout);
  724. this.updateDom();
  725. }
  726. }
  727. if (notification === "Holiday-Received") {
  728. this.holidayLoaded = true;
  729. if (!payload.success) {
  730. console.error("[MMM-DynamicWeather] Holiday-Receieved failure status");
  731. return;
  732. }
  733. var doUpdate_2 = false;
  734. var todayHolidays_1 = [];
  735. todayHolidays_1 = this.parseHolidays(payload.result.holidayBody);
  736. //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
  737. this.allEffects.forEach(function (effect) {
  738. todayHolidays_1.forEach(function (holidayName) {
  739. if (effect.holiday == holidayName) {
  740. doUpdate_2 = true;
  741. effect.doDisplay = true;
  742. _this_1.hasHolidayEffectsToDisplay = true;
  743. }
  744. });
  745. });
  746. //only update the dom if the effects have a holiday to show today (unless weather and date effects exist and weather has finished loading)
  747. if (doUpdate_2 || (this.weatherLoaded && (this.hasDateEffectsToDisplay || this.hasWeatherEffectsToDisplay))) {
  748. this.doShowEffects = true;
  749. clearTimeout(this.effectDurationTimeout);
  750. clearTimeout(this.effectDelayTimeout);
  751. this.updateDom();
  752. }
  753. }
  754. }
  755. catch (error) {
  756. console.error("[MMM-DynamicWeather] Error occured in notification received: ", error);
  757. }
  758. },
  759. });