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
    58 Posts 10 Posters 3.4k Views 9 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 @bloodknot
      last edited by

      @kristjanesperanto
      It looks like something also happened to showalert:

      http://magicmirrorip:8080/api/module/alert/showalert?message=Hello&timer=2000&apiKey=********-****-****-****-**********

      TypeError: Cannot read properties of undefined (reading 'showalert')
          at Class.answerModuleApi (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/API/api.js:457:35)
          at /home/bloodknot/MagicMirror/modules/MMM-Remote-Control/API/api.js:296:14
          at Layer.handleRequest (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/lib/layer.js:152:17)
          at next (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/lib/route.js:157:13)
          at Route.dispatch (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/lib/route.js:117:3)
          at handle (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:435:11)
          at Layer.handleRequest (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/lib/layer.js:152:17)
          at /home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:295:15
          at param (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:600:14)
          at param (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:610:14)
          at param (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:610:14)
          at processParams (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:664:3)
          at next (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:291:5)
          at /home/bloodknot/MagicMirror/modules/MMM-Remote-Control/API/api.js:148:7
          at Layer.handleRequest (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/lib/layer.js:152:17)
          at trimPrefix (/home/bloodknot/MagicMirror/modules/MMM-Remote-Control/node_modules/router/index.js:342:13)
      
      KristjanESPERANTOK 1 Reply Last reply Reply Quote 0
      • KristjanESPERANTOK Offline
        KristjanESPERANTO Module Developer @bloodknot
        last edited by

        @bloodknot Thanks for reporting. Release v4.2.1 should fix it. Please check 🙂

        B 1 Reply Last reply Reply Quote 0
        • B Offline
          bloodknot @KristjanESPERANTO
          last edited by

          @KristjanESPERANTO
          I don’t get a failure, however the alert/showalert function does not work:

          {"success":false,"message":"Module alert does not have any actions defined."}
          
          KristjanESPERANTOK 1 Reply Last reply Reply Quote 0
          • KristjanESPERANTOK Offline
            KristjanESPERANTO Module Developer @bloodknot
            last edited by

            @bloodknot Thanks for the quick feedback. Okay, that was still progress. Now please try v4.2.2.

            B 2 Replies Last reply Reply Quote 0
            • B Offline
              bloodknot @KristjanESPERANTO
              last edited by

              @KristjanESPERANTO
              That seems to have fixed my specific problem. Thank you!!!
              I have tested:
              http://magicmirror2:8080/api/monitor/on

              1 Reply Last reply Reply Quote 0
              • 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 Module Developer @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 Module Developer @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 Offline
                                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.

                                J 1 Reply Last reply Reply Quote 0
                                • J Offline
                                  jakabasej4 @KristjanESPERANTO
                                  last edited by

                                  This post is deleted!
                                  1 Reply Last reply Reply Quote -1

                                  Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                  Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                  With your input, this post could be even better 💗

                                  Register Login
                                  • 1
                                  • 2
                                  • 3
                                  • 3 / 3
                                  • 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