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.

    MMM-Remote-Control

    Scheduled Pinned Locked Moved Utilities
    57 Posts 9 Posters 2.4k Views 8 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.
    • V Offline
      vtek @vtek
      last edited by

      said in MMM-Remote-Control:

      hey guys…

      having some issues using the shutdown/reboot commands…they throw this error, even though I have the API key in the config

      {“success”:false,“message”:“Forbidden: API Key Not Provided!”}

      here’s the config

                  {
                          module: 'MMM-Remote-Control',
                          // position: 'bottom_left', // Required to show URL/QR code on mirror
                          // you can hide this module afterwards from the remote control itself
                          config: {
                                  showModuleApiMenu: true,
                                  secureEndpoints: true,
                                  apiKey: "111111111-2222-3333-4444-555555555555",
                                  customCommand: {
                                                  monitorOnCommand: 'loginctl unlock-session 1',
                                                  monitorOffCommand: 'loginctl lock-session 1',
                                                  shutdownCommand: 'systemctl poweroff',
                                                  rebootCommand: 'systemctl reboot',  // Optional, See "Using Custom Commands" below
                                                  },
      
                  }
                  },
      

      i figure it out…had to append the apiKey at the end of the url for all commands
      http://192.168.1.5:8888/api/command/rebootCommand?apiKey=111111111-2222-33333-4444

      KristjanESPERANTOK 1 Reply Last reply Reply Quote 2
      • R Offline
        rkorell @KristjanESPERANTO
        last edited by

        @KristjanESPERANTO Dear Kristijan,

        after a long time I finally managed to see your “new” modul.
        First of all: Thanks a lot for your effort, again - nice piece!

        In the past few days I’ve completely rebuilt my mirror and migrated it to trixie as well as to the actual mirror and node versions.

        I ran into a reproducible issue with the restart functionality when MagicMirror is managed by pm2 (which is the recommended setup per the official MagicMirror documentation).

        The Problem

        When triggering a restart via the Remote-Control UI (or the /api/restart endpoint), MagicMirror enters an endless crash-loop with EADDRINUSE: address already in use :::8080.

        Root Cause
        The handleRestart function in node_helper.js (lines 717-741) uses the Electron-native restart mechanism:

        const {app} = require("electron");
        app.relaunch();
        app.quit();
        

        This works fine in standalone mode, but creates a race condition with pm2:

        1. app.relaunch() spawns a new Electron instance (child of the current process)
        2. app.quit() terminates the current Electron instance
        3. pm2 detects the termination as a crash and spawns another Electron instance
        4. Now two Electron instances compete for port 8080 → EADDRINUSE → both crash → pm2 keeps restarting → infinite loop

        The only way to recover is to manually identify and kill the orphaned Electron process, then trigger a clean restart via touch config.js (which pm2’s file-watch picks up).

        Interestingly, the catch-block fallback for server mode (lines 726-739) already does it correctly — it calls process.exit(0) and lets the process manager handle the restart. The Electron code path just doesn’t account for the pm2 scenario.

        Possible Fix

        When running under pm2, the Electron-native app.relaunch() should be skipped entirely.

        pm2 can be detected via environment variables like PM2_HOME, pm_id, or PM2_USAGE:

        handleRestart (query, res) {
          try {
            const {app} = require("electron");
            if (!app) { throw "Could not get Electron app instance."; }
        
            // When running under pm2, don't use app.relaunch() — pm2 handles restart
            if (process.env.PM2_HOME || process.env.pm_id !== undefined) {
              Log.log("Running under pm2, exiting cleanly for process manager restart...");
              this.sendResponse(res, undefined, {action: "RESTART", info: "Exiting for pm2 restart..."});
              setTimeout(() => app.quit(), 1000);
              return;
            }
        
            this.sendResponse(res, undefined, {action: "RESTART", info: "Restarting Electron..."});
            app.relaunch();
            app.quit();
          } catch (error) {
            // ... existing server mode fallback ...
          }
        }
        

        Environment

        • MagicMirror 2.34.0
        • MMM-Remote-Control 4.2.2 (commit b854832)
        • Node.js v22, Electron 39.5.2
        • Raspberry Pi 5, Debian 13 (Trixie)
        • Process manager: pm2 with file-watch on config.js

        Workaround

        For now, I’ve documented this for my setup: never use the restart button in Remote-Control. Monitor ON/OFF works fine, only the restart is
        affected.

        Thanks for considering this — happy to test any fix if needed!

        Warmest regards,
        Ralf

        KristjanESPERANTOK 1 Reply Last reply Reply Quote 1
        • KristjanESPERANTOK Online
          KristjanESPERANTO Module Developer @vtek
          last edited by

          Hi @vtek, glad you figured it out! Just for reference: when secureEndpoints: true is set, the API key can be passed in two ways:

          1. URL parameter: ?apiKey=YOUR_KEY
          2. HTTP header: Authorization: apiKey YOUR_KEY

          Also, starting with v4.2.4 the error message now directly hints at the solution, so the next person running into this should find it faster 🙂

          1 Reply Last reply Reply Quote 0
          • KristjanESPERANTOK Online
            KristjanESPERANTO Module Developer @rkorell
            last edited by

            Hi @rkorell, thank you for the detailed bug report — the root cause analysis was spot on and made it straightforward to fix!

            The fix is included in v4.2.4: when MMM-Remote-Control detects it’s running under pm2 (via PM2_HOME or pm_id environment variables), it now skips app.relaunch() and only calls app.quit(), letting pm2 handle the restart cleanly.

            Would be great if you could confirm it works on your setup!

            R 1 Reply Last reply Reply Quote 0
            • R Offline
              rkorell @KristjanESPERANTO
              last edited by

              @KristjanESPERANTO Dear Kristijan,
              just tested v4.2.4 — works perfectly! Restart via the Remote-Control UI now completes cleanly
              under pm2, no orphaned Electron process, no port conflict. Exactly the behavior you’d expect.

              I also noticed you added a dedicated handleRestart.test.js with 210 lines of unit tests covering
              both the pm2 and standalone code paths — that’s really impressive and goes well beyond just a
              quick fix. Having proper test coverage for this kind of dual-mode behavior is exactly the right
              thing to do. Much appreciated!

              Thanks for the incredibly fast turnaround and the quality of the fix. Consider this confirmed
              working on:

              • MagicMirror 2.34.0
              • MMM-Remote-Control 4.2.4
              • Node.js v22, Electron 39.5.2
              • Raspberry Pi 5, Debian 13 (Trixie)
              • pm2 with file-watch

              Warmest regards,
              Ralf

              KristjanESPERANTOK 1 Reply Last reply Reply Quote 1
              • KristjanESPERANTOK Online
                KristjanESPERANTO Module Developer @rkorell
                last edited by

                @rkorell Thank you very much for this feedback and appreciation 🙂 It’s interesting that you took a deeper look at the changes.

                1 Reply Last reply Reply Quote 0
                • 1
                • 2
                • 3
                • 4
                • 5
                • 6
                • 3 / 6
                • First post
                  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