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.

    run Linux command from a mm2 module

    Scheduled Pinned Locked Moved Development
    20 Posts 5 Posters 6.7k Views 5 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.
    • A Offline
      autonomus
      last edited by

      Hello,

      My following question is very basic and that’s because I have no JS experience whatsoever.

      I’m trying to build a module that reads the content of a text file and display it on MM2.

      So I want the module to run the “cat” linux command and display its output. This will be refreshed on some interval as the text file will change.

      Is there’s a module that already does something similar?

      I looked at helloword default module but the text variable is a static string. I tried to add $USER to see if it’ll get the Linux env var value in there but it didn’t.

      I would be very thankful if anyone could provide me some pointers on how to go forward with this.

      strawberry 3.141S 1 Reply Last reply Reply Quote 0
      • strawberry 3.141S Offline
        strawberry 3.141 Project Sponsor Module Developer @autonomus
        last edited by

        @autonomus the problem with the helloworld module is, that is only running in the browser environment, so it doesn’t have access to linux in that sense. What you need is a node_helper which has access to your machine.

        A good example is the pir sensor module https://github.com/paviro/MMM-PIR-Sensor/blob/master/node_helper.js#L59 In this line it executes a linux command as a child process.

        If you check the documentation you can get the response of it in a callback https://nodejs.org/dist/latest-v10.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback

        If you need more information about node helpers you can check the docs here https://github.com/MichMich/MagicMirror/tree/master/modules#the-node-helper-node_helperjs

        Please create a github issue if you need help, so I can keep track

        A Mykle1M 2 Replies Last reply Reply Quote 1
        • A Offline
          autonomus @strawberry 3.141
          last edited by

          @strawberry-3-141 , thanks for the info. I’m starting to understand how this would work, but I can’t get it to run yet. Can you please take a quick look at my code to point me to what I’m doing wrong.

          The missing piece is how to get the output from the Linux command and then pass it to the screen. How do I pass text to the Dom?

          Also is my schedule update the right way to make the module rerun the command and refresh the screen?

          //MMM-pichan.js
          Module.register(‘MMM-pichan’,{

          requiresVersion: "2.1.0",
          
          start: function() {
          Log.log('Starting module: ' + this.name);
          },
          

          });

          //node__helper.js
          var NodeHelper = require(‘node_helper’);
          const exec = require(‘child_process’).exec;

          module.exports = NodeHelper.create({

          start: function () {
          this.scheduleUpdate(0);
          },
          
          readfile: function () {
          //exec("cat /home/pi/Documents/PiChanServer/pichan_status.log", null);
          exec("cat /home/pi/Documents/PiChanServer/pichan_status.log", (error, stdout, stderr) => {
          	if (error) {
          		console.error(`exec error: ${error}`);
          		return;
          	}
          	console.log(`stdout: ${stdout}`);
          });
          },
          
          scheduleUpdate: function(delay, fn) {
          var nextLoad = 3000;
          if (typeof delay !== 'undefined' && delay >= 0) {
              nextLoad = delay;
          }
          
          var self = this
          setTimeout(function() {
              self.readfile();
          }, nextLoad);
          }
          

          });

          1 Reply Last reply Reply Quote 0
          • S Do not disturb
            sdetweil
            last edited by sdetweil

            the two parts of a module talk to each other thru socket notification events…

            the node_helper can interact with the system ,but not the dom, and the module (js) interacts with the dom and not the system…

            the two sides would use the sendSocketNotification(event_id, buffer) method…

            each would have a method called socketNotificationReceived(event_id, buffer) that will be called when the event arrives…

            the buffer can be any kind of data. formatted or not.

            to open the socket the first time, the module.js MUST be the first side to sendSocketNotification().

            typically the module sends the config info to the node_helper when its starts up.

            this is another event notification, which is called notificationReceived(event, buffer, sender)
            there are a a few builtin events, I use the ‘ALL_MODULES_STARTED’ event to send my module config to my helper and open the socket.
            see the doc here for the additional specifics
            https://github.com/MichMich/MagicMirror/tree/master/modules

            the event id strings for socketnotification are completely up to you… the MM system does not send socket notifications. it DOES send notifications (notice no ‘socket’) to the notificationReceived() method

            but summary

            • create both files (per the doc)

            • when module receives the ‘ALL_MODULES_STARTED’ event, send a socket notification from the module to the helper to open the communications channel

            • when the node_helper gets new data, it sends a socket notification (will ONLY be to the module(js)) with the data

            • the module(js) uses the data to update the dom

            • if the module(js) decides when there should be new data, then the module sends a socket notification to the helper, and the helper responds with a socket notification with the new data (if any).

            Sam

            How to add modules

            learning how to use browser developers window for css changes

            1 Reply Last reply Reply Quote 2
            • Mykle1M Offline
              Mykle1 Project Sponsor Module Developer @strawberry 3.141
              last edited by

              @strawberry-3-141 said in run Linux command from a mm2 module:

              A good example is the pir sensor module https://github.com/paviro/MMM-PIR-Sensor/blob/master/node_helper.js#L59 In this line it executes a linux command as a child process.

              I’m quoting your post of 5 months ago. This is exactly what I needed to do. I looked at the requirements and commands in the PIR-Sensor node_helper.js.#L59. With that, I added const exec = require(‘child_process’).exec; and built my function

              getTerminal: function(url) {
                    var self= this;
                    exec("sensors").stdout.on('data', function(stdout) {
                    var results = stdout;
                    console.log(results);
                    self.sendSocketNotification("TERMINAL_RESULT", results);
                  })
                },
              

              Success!

              Create a working config
              How to add modules

              S 1 Reply Last reply Reply Quote 0
              • S Do not disturb
                sdetweil @Mykle1
                last edited by sdetweil

                @mykle1 you didn’t need to do this

                var results = stdout;
                

                Just use stdout as the variable name in the console log and sendsocketnotification

                Every wasted instruction adds to the pgm size, and CPU cycles used, which could be applied somewhere else.

                Also makes maintenance harder cause u might not remember why you did something.

                Sam

                How to add modules

                learning how to use browser developers window for css changes

                Mykle1M 1 Reply Last reply Reply Quote 1
                • Mykle1M Offline
                  Mykle1 Project Sponsor Module Developer @sdetweil
                  last edited by

                  @sdetweil

                  Yes sir. Duly noted. And thanks for the instruction. I try to retain all the tidbits that are given but I find myself having to relearn much of what I thought I already knew. Can you say, “Alzheimers?” :-)

                  Thanks again.

                  Create a working config
                  How to add modules

                  1 Reply Last reply Reply Quote 0
                  • Mykle1M Offline
                    Mykle1 Project Sponsor Module Developer
                    last edited by Mykle1

                    I guess I celebrated a little prematurely. Yes, I can see the data in the terminal and send it to the module.js file. However, I am unable to convert it into usable data, such as an array of objects. I’ve tried all evening with no luck. The closest I’ve gotten is single object that contains all the data:

                    0:
                    stdout:"nouveau-pci-0100↵Adapter: PCI adapter↵fan1:        1170 RPM↵temp1:        +43.0°C  (high = +95.0°C, hyst =  +3.0°C)↵                       (crit = +105.0°C, hyst =  +5.0°C)↵                       (emerg = +135.0°C, hyst =  +5.0°C)↵↵coretemp-isa-0000↵Adapter: ISA adapter↵Core 0:       +46.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 1:       +41.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 2:       +46.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 3:       +38.0°C  (high = +83.0°C, crit = +99.0°C)↵↵f71858fg-isa-0a00↵Adapter: ISA adapter↵+3.3V:        +3.31 V  ↵3VSB:         +3.30 V  ↵Vbat:         +3.20 V  ↵fan1:        1910 RPM↵fan2:        1069 RPM↵fan3:           0 RPM  ALARM↵temp1:        +34.5°C  (high = +70.0°C, hyst = +60.0°C)↵temp2:        +29.5°C  (high = +100.0°C, hyst = +85.0°C)↵temp3:        +36.4°C  (high = +100.0°C, hyst = +85.0°C)↵↵"
                    

                    Using this:

                    getTerminal: function(url) {
                          var self= this;
                    //      exec("sensors", (err, stdout, stderr) => console.log(stdout));
                          exec("sensors").stdout.on('data', function(stdout) {
                          //console.log(JsonConvert.SerializeObject(stdout));
                    
                        var s = stdout;
                       var parts = s.split(':');
                       var jobj = {};
                       for(i=0;i < parts.length;i+=2)
                       {
                          jobj[parts[i]]=parts[i+1];
                       }
                       console.log(JSON.stringify(jobj));
                    

                    I’m stuck. haha. I am grateful for any advice.

                    Peace!

                    Create a working config
                    How to add modules

                    S ? 2 Replies Last reply Reply Quote 0
                    • S Do not disturb
                      sdetweil @Mykle1
                      last edited by

                      @mykle1 let me see what I can do.
                      Will be tomorrow.

                      Sam

                      How to add modules

                      learning how to use browser developers window for css changes

                      Mykle1M 1 Reply Last reply Reply Quote 0
                      • ? Offline
                        A Former User @Mykle1
                        last edited by A Former User

                        @mykle1
                        You can use Regular Expression for getting matched text with pattern.

                        var s = stdout
                        var fan1 = new RegExp("fan1\:\s+([0-9]+ RPM)")
                        var fan1_found = s.match(fan1)
                        console.log(fan1_found, fan1_found[1])
                        

                        Not tested in real PC, so there could be a mistake.

                        Mykle1M 1 Reply Last reply Reply Quote 0
                        • Mykle1M Offline
                          Mykle1 Project Sponsor Module Developer @Guest
                          last edited by

                          @sean

                          First, thank you for your input. I do appreciate it.

                          1. Adding your suggestion results in an uncaught exception. . . TypeError: Cannot read property ‘1’ of null

                          2. Using your suggestion and taking out the “[1]” results in an array with a single object

                          Create a working config
                          How to add modules

                          ? 1 Reply Last reply Reply Quote 0
                          • ? Offline
                            A Former User @Mykle1
                            last edited by

                            @mykle1
                            null means not found. Maybe my regular espression pattern was wrong. As I wrote, it was not tested.
                            However if you find proper expression pattern, it will return matched string. Google it about regular expression. That is a standard way to search or replace text by pattern in most of program languages.

                            Mykle1M 1 Reply Last reply Reply Quote 1
                            • Mykle1M Offline
                              Mykle1 Project Sponsor Module Developer @Guest
                              last edited by Mykle1

                              @sean

                              ok thank you. This seems like a good place to start.

                              https://www.regular-expressions.info/

                              Create a working config
                              How to add modules

                              ? 1 Reply Last reply Reply Quote 0
                              • ? Offline
                                A Former User @Mykle1
                                last edited by A Former User

                                @mykle1

                                • https://www.w3schools.com/jsref/jsref_obj_regexp.asp
                                • https://www.w3schools.com/jsref/jsref_match.asp
                                  See these also.
                                Mykle1M 1 Reply Last reply Reply Quote 1
                                • Mykle1M Offline
                                  Mykle1 Project Sponsor Module Developer @Guest
                                  last edited by

                                  @sean

                                  See these also.

                                  Thanks!

                                  Create a working config
                                  How to add modules

                                  1 Reply Last reply Reply Quote 0
                                  • Mykle1M Offline
                                    Mykle1 Project Sponsor Module Developer @sdetweil
                                    last edited by

                                    @sdetweil said in run Linux command from a mm2 module:

                                    let me see what I can do.
                                    Will be tomorrow.

                                    Thanks! Anything you can offer will be much appreciated.

                                    This what I have, and sent to the module.js
                                    0_1543457816014_Screenshot from 2018-11-28 21-11-58.png

                                    Create a working config
                                    How to add modules

                                    ? 1 Reply Last reply Reply Quote 0
                                    • ? Offline
                                      A Former User @Mykle1
                                      last edited by

                                      @mykle1
                                      test.js

                                      var str = `nouveau-pci-0100↵Adapter: PCI adapter↵fan1:        1170 RPM↵temp1:        +43.0°C  (high = +95.0°C, hyst =  +3.0°C)↵                       (crit = +105.0°C, hyst =  +5.0°C)↵                       (emerg = +135.0°C, hyst =  +5.0°C)↵↵coretemp-isa-0000↵Adapter: ISA adapter↵Core 0:       +46.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 1:       +41.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 2:       +46.0°C  (high = +83.0°C, crit = +99.0°C)↵Core 3:       +38.0°C  (high = +83.0°C, crit = +99.0°C)↵↵f71858fg-isa-0a00↵Adapter: ISA adapter↵+3.3V:        +3.31 V  ↵3VSB:         +3.30 V  ↵Vbat:         +3.20 V  ↵fan1:        1910 RPM↵fan2:        1069 RPM↵fan3:           0 RPM  ALARM↵temp1:        +34.5°C  (high = +70.0°C, hyst = +60.0°C)↵temp2:        +29.5°C  (high = +100.0°C, hyst = +85.0°C)↵temp3:        +36.4°C  (high = +100.0°C, hyst = +85.0°C)↵↵`
                                      
                                      var pattern = [
                                        "(fan[0-9]):[\\s]+([0-9]+ RPM)",
                                        "(temp[0-9]):[\\s]+(\\+[0-9\\.]+°C)",
                                      ]
                                      for (i = 0; i < pattern.length; i++) {
                                        var rx = new RegExp(pattern[i], "g")
                                        var found
                                        do {
                                          found = rx.exec(str)
                                          if (found) console.log(found[1], found[2])
                                        } while(found)
                                      }
                                      

                                      RESULT
                                      0_1543487861366_test1.png

                                      Mykle1M 1 Reply Last reply Reply Quote 1
                                      • Mykle1M Offline
                                        Mykle1 Project Sponsor Module Developer @Guest
                                        last edited by Mykle1

                                        @sean said in run Linux command from a mm2 module:

                                        RESULT

                                        Excellent sean! Working here as well. You have my eternal gratitude. :thumbsup:

                                        EDIT

                                        Using your example above as a guide I was able to add to the pattern array successfully.

                                        My addition
                                        "(Core [0-9]):[\\s]+(\\+[0-9\\.]+°C)"

                                        Result
                                        0_1543544648175_Screenshot from 2018-11-29 21-19-19.png

                                        Now I’ll do the ones I want. Thank you again, sean. This is awesome!

                                        Create a working config
                                        How to add modules

                                        S 1 Reply Last reply Reply Quote 0
                                        • S Do not disturb
                                          sdetweil @Mykle1
                                          last edited by

                                          @mykle1 @sean nice work. Sorry I ran out of time.

                                          Sam

                                          How to add modules

                                          learning how to use browser developers window for css changes

                                          Mykle1M 1 Reply Last reply Reply Quote 0
                                          • Mykle1M Offline
                                            Mykle1 Project Sponsor Module Developer @sdetweil
                                            last edited by

                                            @sdetweil

                                            No worries, bro. I appreciate your interest and concern. I’m sure I’ll need help in the future. You can get in on that. :-)

                                            Create a working config
                                            How to add modules

                                            1 Reply Last reply Reply Quote 0

                                            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 / 1
                                            • 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