Been working on my MagicMirror for a several weeks now, and GooglePhotos has been working great up until a few days ago. Now it just gets stuck showing “Loading…” from startup and just doesn’t display photos anymore. I’ve tried uninstalling the module, reinstalling, running generate_token_v2.js again, and still doesn’t load. There are no console errors and the Google API console shows no traffic since the photos stopped loading but also no errors either. Not sure what else I should be checking for.
Read the statement by Michael Teeuw here.
Posts
-
MMM-GooglePhotos stuck on "Loading..."
-
RE: Need help building two modules that communicate with each other
@sdetweil after modifying the send/receive notifications, and checking the console logs, I verified that the Database is sending the correct information and the List is receiving the correct information. Which is much closer than I was before so Thank you! However, it doesn’t look like the List is doing anything with the information. The List module is only displaying a header and nothing else. Updated code is below.
MMM-MealList.js
Module.register("MMM-MealList", { defaults: { checkedItems: [], updateInterval: 5000, // Update every 5 seconds (adjust as needed) }, getStyles: function () { return ["MMM-MealList.css"]; }, start: function () { console.log("MMM-MealList module started"); this.loaded = false; this.sendNotification("MMM-MEALLIST-INIT"); this.scheduleUpdate(); }, notificationReceived: function (notification, payload) { console.log("Received notification:", notification); if (notification === "MMM-MEALDATABASE-CHECKED_ITEMS") { this.config.checkedItems = payload; this.updateDom(); } }, getDom: function () { var wrapper = document.createElement("div"); wrapper.className = "MMM-MealList"; var header = document.createElement("div"); header.className = "list-header"; header.appendChild(document.createTextNode("Checked Items")); wrapper.appendChild(header); var list = document.createElement("ul"); list.className = "checked-list"; this.config.checkedItems.forEach((item) => { var listItem = document.createElement("li"); listItem.appendChild(document.createTextNode(item)); list.appendChild(listItem); }); wrapper.appendChild(list); return wrapper; }, scheduleUpdate: function () { var self = this; setInterval(function () { console.log("MMM-MealList update requested"); self.sendNotification("MMM-MEALLIST-UPDATE_REQUEST"); }, this.config.updateInterval); }, })
-
RE: Need help building two modules that communicate with each other
@sdetweil thank you for the quick reply. I’ll give that a shot and let you know if that fixes it.
-
Need help building two modules that communicate with each other
I’ll try to explain what I’m trying to do as simply as I can, but forgive me as I haven’t coded since college and have had a lot of AI help to get to this point. I’m trying to create two modules. The first is MMM-MealDatabase which is a three column list of items. The items on this list will need display their own unique icon when “unchecked”, and the icon will change to a checkmark when the item is “checked”. The checked or unchecked state of each item is saved locally so that when MagicMirror is exited and restarted, it retains which items were checked or not. This module will be hidden by MMM-Modulebar when not being used to select or de-select the items. The other module MMM-MealList will display a list of whatever items are “checked” in the MMM-MealDatabase module.
So far, I’ve been able to get the MealDatabase module to display and behave correctly. I can check the items and the state saves after closing MM and restarting. The problem I’m running into, is the MealList module isn’t displaying anything. I am getting the “Sending checked items” log when checking the console. But that’s as far as I’m getting. Posting the code from both .js files below. Hoping someone much smarter than me can take a look and help me out.
MMM-MealDatabase.js
Module.register("MMM-MealDatabase", { defaults: { meals: { chicken: ["Chicken Dish 1", "Chicken Dish 2"], beef: ["Beef Dish 1", "Beef Dish 2"], pork: ["Pork Dish 1", "Pork Dish 2"], }, iconMapping: { "Chicken Dish 1": "fa fa-drumstick-bite", "Chicken Dish 2": "fa fa-drumstick-bite", "Beef Dish 1": "fa fa-cloud-meatball", "Beef Dish 2": "fa fa-cloud-meatball", "Pork Dish 1": "fa fa-bacon", "Pork Dish 2": "fa fa-bacon", }, checkStates: {}, // Ensure that checkStates is initialized as an empty object }, getStyles: function () { return ["MMM-MealDatabase.css"]; }, start: function () { console.log("MMM-MealDatabase module started"); this.loaded = false; this.loadCheckStates(); // Load check states from local storage // Send a socket notification to notify other modules about the current checked items this.sendCheckedItems(); this.sendSocketNotification("MMM-MEALDATABASE-INIT", this.config.meals); }, sendCheckedItems: function () { console.log("Sending checked items"); const checkedItems = Object.keys(this.config.checkStates).filter(meal => this.config.checkStates[meal]); this.sendSocketNotification("MMM-MEALDATABASE-CHECKED_ITEMS", checkedItems); }, getDom: function () { var wrapper = document.createElement("div"); wrapper.className = "MMM-MealDatabase"; wrapper.appendChild(this.createColumn("Chicken", "chicken")); wrapper.appendChild(this.createColumn("Beef", "beef")); wrapper.appendChild(this.createColumn("Pork", "pork")); return wrapper; }, createColumn: function (category, mealType) { var column = document.createElement("div"); column.className = "category"; var header = document.createElement("div"); header.className = "column-header"; header.appendChild(document.createTextNode(category)); column.appendChild(header); this.config.meals[mealType].forEach((meal) => { var item = document.createElement("div"); item.className = "item"; var checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.id = meal; // Use a unique identifier for each checkbox checkbox.className = "checkbox"; // Set the checked state based on the stored state checkbox.checked = this.getCheckState(meal); var label = document.createElement("label"); label.appendChild(checkbox); label.appendChild(document.createTextNode(meal)); item.appendChild(label); // Add change event to update the checked state checkbox.addEventListener("change", () => { this.updateCheckState(meal, checkbox.checked); }); column.appendChild(item); }); return column; }, updateCheckState: function (meal, isChecked) { // Update the local storage and the module's config localStorage.setItem(`MMM-MealDatabase-${meal}`, isChecked ? "checked" : "unchecked"); this.config.checkStates[meal] = isChecked; // Send checked items to other modules this.sendCheckedItems(); this.updateDom(); }, getCheckState: function (meal) { // Retrieve the check state from local storage return localStorage.getItem(`MMM-MealDatabase-${meal}`) === "checked"; }, loadCheckStates: function () { // Load check states from local storage into the module's config Object.keys(this.config.meals).forEach((mealType) => { this.config.meals[mealType].forEach((meal) => { this.config.checkStates[meal] = this.getCheckState(meal); }); }); }, });
MMM-MealList.js
Module.register("MMM-MealList", { defaults: { checkedItems: [], updateInterval: 10000, // Update every 10 seconds (adjust as needed) }, getStyles: function () { return ["MMM-MealList.css"]; }, start: function () { console.log("MMM-MealList module started"); this.loaded = false; this.sendSocketNotification("MMM-MEALLIST-INIT"); this.scheduleUpdate(); }, socketNotificationReceived: function (notification, payload) { console.log("Received notification:", notification); if (notification === "MMM-MEALDATABASE-CHECKED_ITEMS") { this.config.checkedItems = payload; this.updateDom(); } }, getDom: function () { var wrapper = document.createElement("div"); wrapper.className = "MMM-MealList"; var header = document.createElement("div"); header.className = "list-header"; header.appendChild(document.createTextNode("Checked Items")); wrapper.appendChild(header); var list = document.createElement("ul"); list.className = "checked-list"; this.config.checkedItems.forEach((item) => { var listItem = document.createElement("li"); listItem.appendChild(document.createTextNode(item)); list.appendChild(listItem); }); wrapper.appendChild(list); return wrapper; }, scheduleUpdate: function () { var self = this; setInterval(function () { self.sendSocketNotification("MMM-MEALLIST-UPDATE_REQUEST"); }, this.config.updateInterval); }, });