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.
    • B Offline
      bloodknot @KristjanESPERANTO
      last edited by

      @KristjanESPERANTO
      Sorry for the split message.
      I have successfully tested:
      http://magicmirrorip:8080/api/monitor/on
      http://magicmirrorip:8080/api/monitor/off
      http://magicmirrorip:8080/api/refresh
      http://magicmirrorip:8080/api/reboot
      http://magicmirrorip:8080/api/alert/showalert

      KristjanESPERANTOK 1 Reply Last reply Reply Quote 0
      • 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
                    • 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