• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
MagicMirror Forum
  • Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
A New Chapter for MagicMirror: The Community Takes the Lead
Read the statement by Michael Teeuw here.

triggering a module

Scheduled Pinned Locked Moved Solved Troubleshooting
8 Posts 3 Posters 409 Views 3 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    lucifer6669
    last edited by sdetweil Feb 8, 2025, 10:31 PM Feb 8, 2025, 9:25 PM

    hello all im still new to all this and trying to work my way through all this, I created a chores module that when all chores were marked done it would trigger the MMM-Fireworks module. but since the fireworks module updated it no longer triggers the fireworks and now im at a loss on how to get it to work. any help is greatly appreciated.

    here is my chores module:

    Module.register("MMM-DailyChoreGridColor", {
        defaults: {
            updateInterval: 60000, // 1 minute
        },
    
        start: function() {
            this.choreList = {
                MONDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Read", done: false }],
                TUESDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Read", done: false }],
                WEDNESDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Read", done: false }],
                THURSDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Read", done: false }],
                FRIDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Read", done: false }],
                SATURDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false }],
                SUNDAY: [
                    { chore: "Wash dishes", done: false },
                    { chore: "Take Out Trash", done: false },
                    { chore: "Wipe Down Counters", done: false },
                    { chore: "Pick Up Poop", done: false },
                    { chore: "Feed Pets", done: false },
                    { chore: "Play With Petey", done: false },
                    { chore: "Clean Room", done: false },
                    { chore: "Clean Bathroom", done: false },
                    { chore: "Laundry", done: false }],
    
            };
        },
    
        getDom: function() {
            const wrapper = document.createElement("div");
            wrapper.innerHTML = "<h2>Daily Chore List</h2>";
    
            const table = document.createElement("table");
            table.style.width = "100%";
            table.style.margin = "auto";
            table.style.borderCollapse = "collapse";
    
            const headerRow = document.createElement("tr");
            const daysOfWeek = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"];
            daysOfWeek.forEach(day => {
                const dayHeader = document.createElement("th");
                dayHeader.innerHTML = day;
                dayHeader.style.border = "1px solid black";
                dayHeader.style.padding = "10px";
                dayHeader.style.backgroundColor = "#f2f2f2";
                dayHeader.style.textAlign = "center";
                headerRow.appendChild(dayHeader);
            });
            table.appendChild(headerRow);
    
            const maxChores = Math.max(...Object.values(this.choreList).map(day => day.length));
            for (let i = 0; i < maxChores; i++) {
                const choreRow = document.createElement("tr");
                daysOfWeek.forEach(day => {
                    const choreCell = document.createElement("td");
                    const taskDiv = document.createElement("div");
                    const task = this.choreList[day][i];
                    if (task) {
                        const taskText = document.createElement("span");
                        taskText.innerHTML = task.chore;
    
                        const dropdown = document.createElement("select");
                        dropdown.options.add(new Option("X", "false"));
                        dropdown.options.add(new Option("\u2713", "true"));
                        dropdown.value = task.done ? "true" : "false";
                        this.updateDropdownColor(dropdown, task.done);
                        dropdown.style.float = "right";  // Align dropdown to the right
    
                        dropdown.onchange = () => {
                            task.done = dropdown.value === "true";
                            this.updateDropdownColor(dropdown, task.done);
                            console.log(`Task updated: ${task.chore}, Done: ${task.done}`);
    
                            if (this.allChoresDone()) {
                                console.log("All chores done, sending notification");
                                this.sendNotification("ALL_CHORES_DONE");
                            } else {
                                console.log("Not all chores are done yet.");
                            }
                        };
    
                        taskDiv.appendChild(taskText);
                        taskDiv.appendChild(dropdown);
                    }
                    choreCell.appendChild(taskDiv);
                    choreCell.style.border = "1px solid black";
                    choreCell.style.padding = "10px";
                    choreCell.style.textAlign = "center";
                    choreRow.appendChild(choreCell);
                });
                table.appendChild(choreRow);
            }
    
            const clearButton = document.createElement("button");
            clearButton.innerHTML = "Clear All";
            clearButton.style.marginTop = "20px";
            clearButton.onclick = () => {
                Object.keys(this.choreList).forEach(day => {
                    this.choreList[day].forEach(task => {
                        task.done = false;
                    });
                });
                this.updateDom();
                console.log("All chores have been cleared.");
            };
            wrapper.appendChild(clearButton);
    
            wrapper.appendChild(table);
            return wrapper;
        },
    
        updateDropdownColor: function(dropdown, done) {
            if (done) {
                dropdown.style.backgroundColor = "green";
                dropdown.style.color = "white";
            } else {
                dropdown.style.backgroundColor = "red";
                dropdown.style.color = "white";
            }
        },
    
        allChoresDone: function() {
            for (const day in this.choreList) {
                for (const task of this.choreList[day]) {
                    if (!task.done) {
                        console.log(`Task not done: ${task.chore}`);
                        return false;
                    }
                }
            }
            console.log("All chores done: true");
            this.sendNotification("ALL_CHORES_DONE");
            return true;
        }
    });
    

    and here is the Fireworks module:

    Module.register("MMM-Fireworks", {
      defaults: {
        startDateTime: "", // ISO format start time
        duration: 36000,          // Duration in milliseconds (6 hours)
        // p5 Fireworks settings:
        fireworkSpawnChance: 0.5,              // Chance each frame to spawn a new firework
        explosionParticleCount: 40,            // Number of particles per explosion
        // Display settings:
        fullscreen: true,                      // If false, use the defined width/height.
        width: "400px",
        height: "500px",
        // Velocity settings for rocket particles:
        magnitude_high: -19,
        magnitude_low: -8,
        // Trailing effect transparency (alpha value for background):
        transparency: 10,
        // New canvas opacity (0.0 = fully transparent, 1.0 = fully opaque)
        canvasOpacity: 0.5,
        // Module management settings:
        disableAllModules: true,               // Set to false so other modules remain visible.
        keepModules: [],                       // Array of module names to keep active.
        // Text overlay:
        text: "Good Job Buddy"
      },
    
      start: function () {
        this.fireworksActive = false;
        this.disabledModules = [];
        this._p5Instance = null;
      },
    
      // Create the module's container.
      // If fullscreen is true, force full screen; otherwise use the defined width/height.
      getDom: function () {
        const wrapper = document.createElement("div");
        wrapper.id = "fireworksContainer";
        if (this.config.fullscreen) {
          wrapper.style.position = "fixed";
          wrapper.style.top = "0";
          wrapper.style.left = "0";
          wrapper.style.width = "100vw";
          wrapper.style.height = "100vh";
          wrapper.style.zIndex = "9999";
          wrapper.style.background = "transparent";
        } else {
          wrapper.style.position = "relative";
          wrapper.style.width = this.config.width;
          wrapper.style.height = this.config.height;
        }
        
        // Create and append the text overlay element (initially hidden).
        if (this.config.text) {
          const textDiv = document.createElement("div");
          textDiv.id = "fireworksText";
          textDiv.className = "fireworks-text";
          textDiv.innerHTML = this.config.text;
          textDiv.style.display = "none"; // Hidden by default; shown during fireworks.
          wrapper.appendChild(textDiv);
        }
        
        return wrapper;
      },
    
      notificationReceived: function (notification, payload, sender) {
        console.log("Notification received: " + notification);
        if (notification === "ALL_CHORES_DONE") {
          this.startFireworks();
        } else if (notification === "DOM_OBJECTS_CREATED") {
          this.scheduleFireworks();
        }
      },
    
      scheduleFireworks: function () {
        const MAX_DELAY = 2147483647; // Maximum delay in ms (~24.8 days)
        const startTime = new Date(this.config.startDateTime).getTime();
        const currentTime = Date.now();
        const duration = this.config.duration;
    
        if (currentTime < startTime) {
          let delay = startTime - currentTime;
          if (delay > MAX_DELAY) {
            setTimeout(() => this.scheduleFireworks(), MAX_DELAY);
          } else {
            setTimeout(() => this.startFireworks(), delay);
          }
        } else if (currentTime < startTime + duration) {
          this.startFireworks();
        } else {
          console.warn("Fireworks time window has already passed.");
        }
      },
    
      startFireworks: function () {
        this.fireworksActive = true;
        const container = document.getElementById("fireworksContainer");
        container.classList.add("fullscreen");
        
        // Show the text overlay during the fireworks period.
        const textDiv = document.getElementById("fireworksText");
        if (textDiv) {
          textDiv.style.display = "block";
        }
        
        // Do not hide other modules if disableAllModules is false.
        if (this.config.disableAllModules) {
          this.deactivateAndHideModules();
        }
        
        this.initializeP5();
    
        // Play fireworks sound
        const audio = new Audio("MagicMirror/Modules/MMM-Fireworks/fireworks-sound.mp3");
        audio.play();
    
        setTimeout(() => {
          this.stopFireworks();
        }, this.config.duration);
      },
    
      stopFireworks: function () {
        if (this._p5Instance) {
          this._p5Instance.remove();
          this._p5Instance = null;
        }
        const container = document.getElementById("fireworksContainer");
        container.innerHTML = "";
        this.fireworksActive = false;
        if (this.config.disableAllModules) {
          this.reactivateAndShowModules();
        }
      },
    
      deactivateAndHideModules: function () {
        const self = this;
        MM.getModules().enumerate(function (module) {
          if (
            module.name !== "MMM-Fireworks" &&
            self.config.keepModules.indexOf(module.name) === -1
          ) {
            console.log("Hiding module: " + module.name);
            module.hide(500, () => {});
            if (module.suspend) {
              module.suspend();
            }
            self.disabledModules.push(module);
          }
        });
      },
    
      reactivateAndShowModules: function () {
        const self = this;
        this.disabledModules.forEach(function (module) {
          console.log("Showing module: " + module.name);
          module.show(500, () => {});
          if (module.resume) {
            module.resume();
          }
        });
        this.disabledModules = [];
      },
    
      // Integrated p5.js fireworks sketch.
      initializeP5: function () {
        if (this._p5Instance) return;
        const self = this;
        const config = this.config;
        this._p5Instance = new p5(function (p) {
          let fireworks = [];
          let gravity;
          // Optional: clear the canvas fully every 2 minutes to remove ghost trails.
          setInterval(function () {
            console.log("Performing full redraw (clear) every 2 minutes.");
            p.clear();
          }, 2 * 60 * 1000);
          
          p.setup = function () {
            const container = document.getElementById("fireworksContainer");
            p.createCanvas(container.offsetWidth, container.offsetHeight);
            // Set the canvas opacity to the configured value.
            p.canvas.style.opacity = config.canvasOpacity;
            p.colorMode(p.HSB, 255);
            gravity = p.createVector(0, 0.2);
            p.background(0);
          };
          
          p.draw = function () {
            // Use a semi-transparent background for the trailing effect.
            p.background(0, 0, 0, config.transparency);
            
            // Spawn a new firework with the specified probability.
            if (p.random(1) < config.fireworkSpawnChance) {
              fireworks.push(new Firework(p, gravity, config.explosionParticleCount));
            }
            
            // Update and render fireworks.
            for (let i = fireworks.length - 1; i >= 0; i--) {
              fireworks[i].update();
              fireworks[i].show();
              if (fireworks[i].done()) {
                fireworks.splice(i, 1);
              }
            }
          };
          
          // --- Particle Class ---
          class Particle {
            constructor(p, x, y, hu, isFirework) {
              this.p = p;
              this.pos = p.createVector(x, y);
              this.isFirework = isFirework;
              if (this.isFirework) {
                // Rocket's upward velocity based on config values.
                this.vel = p.createVector(0, p.random(config.magnitude_high, config.magnitude_low));
              } else {
                this.vel = p5.Vector.random2D();
                this.vel.mult(p.random(2, 10));
              }
              this.acc = p.createVector(0, 0);
              this.lifespan = 255;
              this.hu = hu;
            }
            applyForce(force) {
              this.acc.add(force);
            }
            update() {
              if (!this.isFirework) {
                this.vel.mult(0.9);
                this.lifespan -= 4;
              }
              this.vel.add(this.acc);
              this.pos.add(this.vel);
              this.acc.mult(0);
            }
            done() {
              return this.lifespan < 0;
            }
            show() {
              this.p.strokeWeight(this.isFirework ? 4 : 2);
              this.p.stroke(this.hu, 255, 255, this.lifespan);
              this.p.point(this.pos.x, this.pos.y);
            }
          }
          
          // --- Firework Class ---
          class Firework {
            constructor(p, gravity, explosionCount) {
              this.p = p;
              this.hu = p.random(255);
              this.firework = new Particle(p, p.random(p.width), p.height, this.hu, true);
              this.exploded = false;
              this.particles = [];
              this.gravity = gravity;
              this.explosionCount = explosionCount;
            }
    
    S C 2 Replies Last reply Feb 8, 2025, 10:35 PM Reply Quote 0
    • L Offline
      lucifer6669 @chrisfr1976
      last edited by Feb 9, 2025, 4:17 PM

      @chrisfr1976 yes! it definitely helps! my kid is going to love it. i linked it to a chore list so when he successfully completes all his chores through out the week the fireworks will set off and give him a little party.

      1 Reply Last reply Reply Quote 0
      • S Offline
        sdetweil @lucifer6669
        last edited by Feb 8, 2025, 10:35 PM

        @lucifer6669 i would use the developers window sources tab

        to put stop on send and receive code

        Sam

        How to add modules

        learning how to use browser developers window for css changes

        L 1 Reply Last reply Feb 8, 2025, 10:42 PM Reply Quote 0
        • L Offline
          lucifer6669 @sdetweil
          last edited by Feb 8, 2025, 10:42 PM

          @sdetweil i apologize but i have no idea what that means

          S 1 Reply Last reply Feb 8, 2025, 10:45 PM Reply Quote 0
          • S Offline
            sdetweil @lucifer6669
            last edited by Feb 8, 2025, 10:45 PM

            @lucifer6669 ctrl-shift-i
            select the sources tab

            find your source in the left nav

            Sam

            How to add modules

            learning how to use browser developers window for css changes

            L 1 Reply Last reply Feb 8, 2025, 10:54 PM Reply Quote 0
            • L Offline
              lucifer6669 @sdetweil
              last edited by Feb 8, 2025, 10:54 PM

              @sdetweil gotcha thank you, i dont know all the terminology. but upon completing all tasks i does send the notification but nothing happens after that

              S 1 Reply Last reply Feb 8, 2025, 11:07 PM Reply Quote 0
              • S Offline
                sdetweil @lucifer6669
                last edited by Feb 8, 2025, 11:07 PM

                @lucifer6669 ok, you can step into his code too

                Sam

                How to add modules

                learning how to use browser developers window for css changes

                1 Reply Last reply Reply Quote 0
                • C Offline
                  chrisfr1976 @lucifer6669
                  last edited by Feb 9, 2025, 12:25 PM

                  @lucifer6669 Hi,
                  See my latest update:

                  https://forum.magicmirror.builders/post/123879

                  You can use a notification now to start a fireworks. You can also send a specific text message to display. I think this solves your issue :)

                  Regards, Chris.

                  L 1 Reply Last reply Feb 9, 2025, 4:17 PM Reply Quote 0
                  • L Offline
                    lucifer6669 @chrisfr1976
                    last edited by Feb 9, 2025, 4:17 PM

                    @chrisfr1976 yes! it definitely helps! my kid is going to love it. i linked it to a chore list so when he successfully completes all his chores through out the week the fireworks will set off and give him a little party.

                    1 Reply Last reply Reply Quote 0
                    • S sdetweil has marked this topic as solved on Feb 12, 2025, 2:17 PM
                    • 1 / 1
                    1 / 1
                    • First post
                      1/8
                      Last post
                    Enjoying MagicMirror? Please consider a donation!
                    MagicMirror created by Michael Teeuw.
                    Forum managed by Sam, technical setup by Karsten.
                    This forum is using NodeBB as its core | Contributors
                    Contact | Privacy Policy