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 954 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

      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 Reply Quote 0
      • S Offline
        sdetweil @aderoks
        last edited by sdetweil

        @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 Reply Quote 0
        • A Offline
          aderoks @sdetweil
          last edited by aderoks

          @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 mumblebajM 3 Replies Last reply Reply Quote 0
          • S Offline
            sdetweil @aderoks
            last edited by sdetweil

            @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 Offline
              sdetweil @aderoks
              last edited by

              @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
              • mumblebajM Offline
                mumblebaj Module Developer @aderoks
                last edited by

                @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 Reply Quote 0
                • A Offline
                  aderoks @mumblebaj
                  last edited by aderoks

                  @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 Reply Quote 0
                  • S Offline
                    sdetweil @aderoks
                    last edited by sdetweil

                    @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 Offline
                      sdetweil @mumblebaj
                      last edited by

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