How to make a Magic Mirror module run at specific time everyday?

47 Views Asked by At

I'm trying to build a a Magic Mirror module. It is supposed to show my favorite restaurant's daily menu on the screen. The menu is stored in the menu.txt file in this structure:

{"Monday": ["Food 1", "Food 2", "Food 3"]}
{"Tuesday": ["Food 4", "Food 5", "Food 6"]}
{"Wednesday": ["Food 7", "Food 8", "Food 9"]}
{"Thursday": ["Food 10", "Food 11", "Food 12"]}
{"Friday": ["Food 13", "Food 14", "Food 15"]}

The food is served until 14 on weekdays, so I want the module to be reloaded exactly at 14:01, and shows the next day's menu. Like this:

If it is a Monday, only the second line of the text file will be shown.
If it is a Tuesday, only the third line of the text file will be shown.
If it is a Wednesday, only the fourth line of the text file will be shown.
If it is a Thursday, only the fifth line of the text file will be shown.
Otherwise, only the first line of the text file will be shown.

I'm new with JS, and can't figure this out. This is the config/config.js entry:

{
  module: "weeklyText",
  position: "top_center",
}

and this is the module's code:

const fs = require("fs");
const path = require("path");

Module.register("weeklyText", {
  defaults: {
    filePath: "modules/weeklyText/menu.txt",
    reloadInterval: 24 * 60 * 60 * 1000, // 24 hours in milliseconds
    showKeyInBold: true,
  },

  start: function () {
    var self = this;

  
    self.updateText();
    self.updateDom();

    // Calculate the delay until 14:01
    const delay = self.calculateDelay();

    // Set a timeout for the first run at 14:01
    setTimeout(function () {
      // Run the first update
      self.runUpdate();

      // Set an interval for subsequent updates every 24 hours
      setInterval(function () {
        self.runUpdate();
      }, self.config.reloadInterval);
    }, delay);
  },

  runUpdate: function () {
    const now = new Date();
    const currentDay = now.getDay();
    const targetLine = (currentDay >= 1 && currentDay <= 4) ? currentDay + 1 : 1;

    this.updateText(targetLine);
    this.updateDom();
  },

  calculateDelay: function () {
    const now = new Date();
    const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 14, 1, 0, 0);
    let delay = targetTime - now;

    if (delay < 0) {
      delay += 24 * 60 * 60 * 1000; // If it's already past 14:01, set the delay for the next day
    }

    return delay;
  },

  updateText: function (targetLine) {
    var self = this;

    // Read text from the file
    try {
      const filePath = path.join(__dirname, self.config.filePath);
      const fileContent = fs.readFileSync(filePath, "utf8");

      // Parse each line as JSON
      const lines = fileContent.split("\n").filter((line) => line.trim() !== "");
      const parsedData = lines.map((line) => JSON.parse(line));

      // Find the target line based on the day of the week
      const targetEntry = parsedData.find((entry, index) => index + 1 === targetLine);

      if (targetEntry) {
        const key = self.config.showKeyInBold ? `<strong>${targetEntry.key}</strong>` : targetEntry.key;
        const listItems = targetEntry.value.map((item) => `<p>${item}</p>`).join("");
        self.config.text = `<div>${key}${listItems}</div>`;
      } else {
        self.config.text = "No entry for the current day.";
      }
    } catch (error) {
      console.error("Error reading or parsing text file:", error.message);
      self.config.text = "Error reading or parsing text file.";
    }
  },

  // Override dom generator.
  getDom: function () {
    var wrapper = document.createElement("div");
    wrapper.className = "thin xlarge bright";
    wrapper.innerHTML = this.config.text;
    return wrapper;
  },
});

Unfortunately, it doesn't work and nothing is shown on the display. What am I doing wrong?

0

There are 0 best solutions below