MagicMirror² v2.5.0 is available! For more information about this release, check out this topic.

run Linux command from a mm2 module



  • 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.



  • @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



  • @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);
    }
    

    });



  • 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).