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
    56 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.
    • KristjanESPERANTOK Offline
      KristjanESPERANTO Module Developer @bloodknot
      last edited by

      @bloodknot Perfect, thank you for testing! 😃

      1 Reply Last reply Reply Quote 0
      • V Offline
        vtek
        last edited by

        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
                                                    },
        
                    }
                    },
        
        V 1 Reply Last reply Reply Quote 0
        • 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 Offline
              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 Offline
                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

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