• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
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.

How to send notification to module via external REST API call?

Scheduled Pinned Locked Moved Development
9 Posts 3 Posters 949 Views 3 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
    aderoks
    last edited by Dec 10, 2021, 7:34 PM

    Re: [Building my first module](using MMM-API) I tried following the module which @PTcrusher has created, i.e. MMM-Piggybank, but still could not understand how the main module.js socketNotificationReceived() method gets called when a notification is sent from the node_helper.js. In my case, I tried sending a socket notification in node_helper.js right from the POST block:

    this.expressApp.post("/date_sent", (req, res) => {
    			//console.log("datePost?", req.body);
    			this.sendSocketNotification("date_sent", req.body);
    			res.status(200).send({status: 200})
    		});
    

    and trying to receive it in module.js:

    socketNotificationReceived: function (notification, payload) {
    			console.log("Receiving notification from MMM-Test");
                if(notification === "date_sent") {
    				console.log("Received");
                        // set dataNotification
                        date_sent(payload);
                        //this.dataNotification = payload;
                        //this.updateDom();
                }
        }
    

    but to no avail. Nothing ever gets printed. If I uncomment the console.log() in the node_helper.js POST method, I can see that the POST request is received fine and well, but the socket notification is lost. Please help me.

    S 1 Reply Last reply Dec 10, 2021, 7:51 PM Reply Quote 0
    • S Away
      sdetweil @aderoks
      last edited by sdetweil Dec 10, 2021, 7:51 PM Dec 10, 2021, 7:51 PM

      @aderoks you have now experienced the shifting value of the ‘this.’ pointer.

      it is sensitive to the context at the time.
      inside the callback of the request, ‘this’ points to the request. NOT the module context.

      that is the reason you will see many times BEFORE the request

      let self = this

      and then in the callback, use self.
      instead of this.

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      A 1 Reply Last reply Dec 11, 2021, 2:23 PM Reply Quote 0
      • A Offline
        aderoks @sdetweil
        last edited by aderoks Dec 11, 2021, 2:25 PM Dec 11, 2021, 2:23 PM

        @sdetweil Thank you for the response. I tried your suggested approach. My code looks like the following now:

        node_helper.js

        const NodeHelper = require("node_helper")
        const bodyParser = require("body-parser")
        const exec = require('child_process').exec
        
        
        module.exports = NodeHelper.create({
        	start: function() {
        		var self = this;
        		
        		this.expressApp.use(bodyParser.json())
        		this.expressApp.use(bodyParser.urlencoded({extended: true}))
        
        		this.expressApp.post("/date_sent", (req, res) => {
        			console.log("datePost?", req.body);
        			self.sendSocketNotification("date_sent", req.body);
        			res.status(200).send({status: 200})
        		});
        		console.log("Starting node helper for: " + this.name);
        	},
        
        
        	socketNotificationReceived: function(noti, payload) {
        		var self = this;
        		
        		if (noti == "date_sent") {
        			console.log("Received date_sent: " + payload);
        			self.sendSocketNotification("date_sent", payload);
        		}
        	}
        })
        
        

        module.js

        socketNotificationReceived: function (notification, payload) {
        			console.log("Receiving notification from MMM-Test");
                    if(notification === "date_sent") {
        				console.log("Received");
                            // set dataNotification
                            date_sent(payload);
                            //this.dataNotification = payload;
                            //this.updateDom();
                    }
            },
        
        date_sent: function(payload) {
              console.log("Date received: " + payload);
        	}
        

        Now, I am seeing that whenever I restart magic mirror, I am having a constant stream of logs with the following line:

        Received date_sent: [object Object]

        This is coming from the socketNotificationReceived method of the node_helper.js itself. I am trying to send the notification again from there, but the socketNotificationReceived method in the module.js still doesn’t print anything.

        S M 3 Replies Last reply Dec 11, 2021, 2:25 PM Reply Quote 0
        • S Away
          sdetweil @aderoks
          last edited by sdetweil Dec 11, 2021, 2:28 PM Dec 11, 2021, 2:25 PM

          @aderoks said in How to send notification to module via external REST API call?:

          socketNotificationReceived method in the module.js still doesn’t print anything.

          you have to open the developers window in the browser, ctrl-shift-i, and select the console tab

          node_helper console output comes out on the terminal, browser side in the browser console

          you can also step thru the modulename.js (browser side) code in the dev window sources tab

          but start: time is pretty early…

          typically the connection isn’t setup until after the module side receives start and sends the config to the helper
          (as the helper can’t see the config directly)

          Sam

          How to add modules

          learning how to use browser developers window for css changes

          1 Reply Last reply Reply Quote 0
          • S Away
            sdetweil @aderoks
            last edited by Dec 11, 2021, 2:43 PM

            @aderoks if you add this to the session/script where u start MM then all the messages will be printed in the terminal window

            export ELECTRON_ENABLE_LOGGING=true

            Sam

            How to add modules

            learning how to use browser developers window for css changes

            1 Reply Last reply Reply Quote 0
            • M Offline
              mumblebaj Module Developer @aderoks
              last edited by Dec 12, 2021, 5:11 AM

              @aderoks said in How to send notification to module via external REST API call?:

              socketNotificationReceived: function (notification, payload) {
              console.log(“Receiving notification from MMM-Test”);
              if(notification === “date_sent”) {
              console.log(“Received”);

              Generally, in the module.js you would use Log.log and it would print to the developer window Console. Or you could just do as Sam suggested and it would print to the terminal window.

              Check out my modules at: https://github.com/mumblebaj?tab=repositories

              A S 2 Replies Last reply Dec 12, 2021, 8:51 AM Reply Quote 0
              • A Offline
                aderoks @mumblebaj
                last edited by aderoks Dec 12, 2021, 8:53 AM Dec 12, 2021, 8:51 AM

                @sdetweil @mumblebaj Thanks so much for your responses. I have been trying to implement them. However, I am facing some obstacles, and at every step, I am feeling that a deeper understanding of the Magic Mirror framework itself is required which I am not being able to find anywhere. Let me start with my problems:

                1. I am using a headless setup with my Raspberry Pi 4B, so my magic mirror is being displayed onto the monitor with which it’s directly connected, but I am doing all the development by opening a remote connection to it from another PC. So I am not understanding which browser window console would give me the output, since the Chromium window which I have open in this remote desktop is perhaps, surely not the one in which the Magic Mirror is running, isn’t it?

                2. I tried giving the export ELECTRON_ENABLE_LOGGING=true code in the module.js, outside of the Module.register statement, since I felt that inside it, there are only functions and not variable declarations. The module refused to even load.

                3. I considered that as you have said, let me consider that the notification is actually being sent to my main module.js file, even though I am not being able to see any output. Now what I actually want to do is refresh the calendar monthly view (I have taken this implementation: https://github.com/KirAsh4/calendar_monthly) with a month that the user will pass in from the REST API call. Here, I am facing the challenge that I don’t really know how the getDom() and refreshDom() functions work and if I can parameterize them, or they are overriden methods with a fixed signature. So, understandably, when I tried to just lamely copy the getDom method into a new one and parameterized it with the passed input and tried to call it from the socketNotificationReceived() method in module.js file to refresh the output to the desired month, nothing happened. Now of course, I don’t even know whether the notification even reached the module.js, but I am assuming it did, based on what all you have said.

                This all is leading me to understand that I need to know more about what underlying JS framework Magic Mirror uses for its development. For instance, when I do Module.register(), what am I actualy doing? Are the functions inside it being made visible for external access? If so, how can I access them? I tried to use MMM-NotificationTrigger’s webhook functionality to achieve my end (https://github.com/MMRIZE/MMM-NotificationTrigger#usewebhook), however, after using MMM-Api (https://github.com/juzim/MMM-Api), I found that whatever custom function I am writing within the Module.register() code block is not being exposed as actions, so that if I try to fire a notification to it using MMM-NotificationTrigger, it probably isn’t collecting it. Which is why I moved to the current approach of exposing my own REST endpoints in node_helper.js and trying to collect data from there. However, now also, I am not being able to achieve my expectation. On the other hand, I now have a stream of “Received date_sent: [object Object]” messages being printed to the console from the socketNotificationReceived function of node_helper.js from the very startup of the application. What mechanism is responsible for sending these notifications? All these are questions which I haven’t found satisfactory answers in the forum, maybe because people already know how this framework works. If so, please point me to the framework I should learn, and I would get to learning it. But please also suggest ways for me to fix these problems in the meantime so that I can get my functionality up and running.

                Sorry for the long response.

                Thank you.

                S 1 Reply Last reply Dec 12, 2021, 2:02 PM Reply Quote 0
                • S Away
                  sdetweil @aderoks
                  last edited by sdetweil Dec 12, 2021, 2:28 PM Dec 12, 2021, 2:02 PM

                  @aderoks let’s start somewhere

                  mm is a normal web page, with little applets (modules). the mm code calls each applet to get their content at getDom() and insert the content on the web page in the configured position:, using normal dynamic html apis. this allows the applets to present info anytime, not just page load time. if they want to change/update their displayed data, they call updateDom(), which informs mm to call their getDom() function to get the latest applet content

                  the code running in the browser (modulename.js) cannot directly read files or touch hardware ( raspi gpio pins for example), so there is an optional ‘server’ side component for each applet, the node_helper.js.
                  the two parts communicate with private socket.io functions.

                  1. that ELECTRON_ENABLE_LOGGING=true is issued in the terminal window where u do npm start. (set an environment variable) or in the bash script used by pm2, installers/mm.sh

                  2. you can use the browser side of mm on any system. you just have to enable it, by setting the allowed connection on config.js
                    address:“0.0.0.0”, and ipWhitelist:[]
                    which means listen for connections from anywhere, and do not restrict source IP addresses. in a home environment, that means any system on your wifi or Ethernet network
                    http://mm_ip-address:mm-config.js-port

                  the env setting in 2 only echos the browser logging on the machine that launched mm…

                  register is the mm function to connect your applet to the mm runtime.
                  you need to read the specifications
                  https://docs.magicmirror.builders/development/introduction.html#general-advice

                  mmm-api proposes to create a distinct API from outside mm, but again address/ipWhitelist control where it can be accessed from.

                  the only mechanism inside mm to communicate between modules is the send/receiveNotification functions. send is a broadcast to all modules. all the built-in modules do this.
                  clock send second/minute/hour/day ticks, calendar sends current entries, weather’s sends etc.

                  MMM-API turns the API requests into send/receiveNotification operations

                  the send/socketNotification functions take a string as the identifier of the event, and an arbitrary untyped value .
                  if a receiving module wants to accept and process the event message,it must understand the format of the data ( aka payload)

                  Sam

                  How to add modules

                  learning how to use browser developers window for css changes

                  1 Reply Last reply Reply Quote 0
                  • S Away
                    sdetweil @mumblebaj
                    last edited by Dec 12, 2021, 2:58 PM

                    @mumblebaj Log.log is just a wrapper for console.log, which lets mm do the loglevel settings in config.js

                    Sam

                    How to add modules

                    learning how to use browser developers window for css changes

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    1 / 1
                    • First post
                      1/9
                      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