MagicMirror Forum

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • Donate
    • Discord
    1. Home
    2. grantc66
    G
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 14
    • Best 0
    • Controversial 0
    • Groups 0

    grantc66

    @grantc66

    0
    Reputation
    457
    Profile views
    14
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    grantc66 Unfollow Follow

    Latest posts made by grantc66

    • Running Python under node.js

      Hi,

      A few weeks ago I started looking into getting notifications onto the mirror from python. Whilst it was relatively straight forward to run python within a shell from the node-helper, I ran into various problems with user privileges and environments.

      To get around this I had a play with rabbitmq. Using amqp for the node end and pika for the python. This opens up a whole world of possibilities for my mirror without having to learn javascript (above the basics & plagiarising code snippets from the built in modules) .

      node-helper end looks like. Sorry it’s a bit messy & I went overboard on the error capture.

      var amqp = require("amqplib/callback_api");
      
      PStart: function starter() {
      const self = this;
        amqp.connect("amqp://localhost", function(err, conn) {
          if (err) {
            console.error("[AMQP]", err.message);
            return setTimeout(starter, 1000);
          }
          conn.on("error", function(err) {
            if (err.message !== "Connection closing") {
              console.error("[AMQP] conn error", err.message);
            }
          });
          conn.on("close", function() {
            console.error("[AMQP] reconnecting");
            return setTimeout(starter, 1000);
          });
          console.log("[AMQP] connected");
          amqpConn = conn;
      
        amqpConn.createChannel(function(err, ch) {
          if (closeOnErr(err)) return;
          ch.on("error", function(err) {
            console.error("[AMQP] channel error", err.message);
          });
          ch.on("close", function() {
            console.log("[AMQP] channel closed");
          });
      
          ch.prefetch(10);
          ch.assertQueue("message", { durable: false }, function(err, _ok) {
            if (closeOnErr(err)) return;
            ch.consume("message", function(msg) {
      try {
       var fp = JSON.parse(msg.content.toString());
          ch.ack(msg);
          } catch (e) {
            closeOnErr(e);
          }
                      if (fp[0].data == "data"){
                      self.sendData({"PlrStat": fp[0].PlrStat, "TrkNxt":fp[0].TrkNext, "Station": fp[0].Station, "Said": fp[0].Said);
                      } else if (fp[0] == "status") {
                      console.log("[MMM-Radio]" + fp[0].status);
                      } else {
                      console.log("Got something");
                      console.log(msg);
                      console.log(fp[0].data);}
      })}, { noAck: false });
            console.log("Worked");
            });
      });
      }  });
      
      function closeOnErr(err) {
        if (!err) return false;
        console.error("[AMQP] error", err);
        amqpConn.close();
        this.Pstart();
        return true;
      }
      
      

      Python end:

      import pika
      
      def to_node(message):
          try:
              channel.basic_publish(exchange='',
                                    routing_key='message',
                                    body=json.dumps(message))
          except Exception:
              connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
              channel = connection.channel()
              channel.queue_declare(queue='message')
              channel.basic_publish(exchange='',
                                    routing_key='message',
                                    body=json.dumps(message))
      
      

      The bit in the exception is the initial setup for the connection, it does occasionally time out so re-establish if the publishing doesn’t work.

      Some useful tutorials on rabbitmq can be found here

      Hope this is a help to some of you who know very little about js & do all the complicated stuff with other languages.

      posted in General Discussion
      G
      grantc66
    • RE: Snowbound on node.js

      @sean Looks like I’ll be learning how to program in Java script 🙂

      Thanks for the tips.

      BTW: I found the issue with the python not running, seems the call from node changes the name of the script so main () had a different name to the import. Didn’t cure the snowboy issue (at least it got called, didn’t respond to wake word though 🤔, I’ll ask on the snowboy forum why that might be), but everything else worked.

      posted in Troubleshooting
      G
      grantc66
    • RE: Snowbound on node.js

      @sdetweil Thanks, had it in there for the pythonshell forgot about it on this version.

      Any pointers on trying exec, my googlefoo is failing to find any help.

      posted in Troubleshooting
      G
      grantc66
    • RE: Snowbound on node.js

      @sean said in Snowbound on node.js:

      MMM-Hotword

      Tried that, it works but its very slow to respond. With the python script, you can say the hotword and give it instructions seamlessly, passing notifications to seems to take forever to respond.

      What I’m trying to get to is understanding what node is doing with the python that stops external modules working & hopefully find away around it. Bit more of a learning exercise, if I can crack this it’ll open up my ability to expand the functionality.

      posted in Troubleshooting
      G
      grantc66
    • RE: Snowbound on node.js

      Got it launching with spawn, the code without snowboy works well (have an issue with getting status messages passed, but I’ll fix that later)

      The version using the snowboy listener works until the snowboy decoder call. Then it stalls, doesn’t crash just freezes. Like the code is running but not communicating back to the python script.

      Couldn’t find anything on exec, this is the spawn version.

      node_helper.js

      const NodeHelper = require("node_helper");
      const spawn = require("child_process").spawn;
      var pythonStarted = false
      
      module.exports = NodeHelper.create({
      
      	socketNotificationReceived: function(notification, payload) {
      		if (notification === "MMM-PIRadio-NOTIFICATION_TEST") {
      			console.log("Working notification system. Notification:", notification, "payload: ", payload);
      
      			this.sendNotificationTest(this.anotherFunction()); //Is possible send objects :)
      		}
      		if (notification === "CONFIG") {
      			console.log("Got a request to start Python:", notification, "payload: ", payload);
      				if(!pythonStarted) {
      					pythonStarted = true;
      					this.python_start();
      				}
      		}
      	},
      
      	sendNotificationTest: function(payload) {
      		this.sendSocketNotification("MMM-PIRadio-NOTIFICATION_TEST", payload);
      	},
      	
      	sendData: function(payload) {
      		this.sendSocketNotification("PiRadiodata", payload);
      	},
      
      	extraRoutes: function() {
      		var self = this;
      		this.expressApp.get("/MMM-PIRadio/extra_route", function(req, res) {
      			// call another function
      			values = self.anotherFunction();
      			res.send(values);
      		});
      	},
      	python_start: function () {
      		const self = this
      
                      const callPy = spawn("/usr/bin/python3.5",["./modules/MMM-PIRadio/PiRadioSnow.py"]);
                      callPy.stdout.on('message', function (message) {
      
      			if (message.hasOwnProperty('status')){
      			console.log("[" + self.name + "]" + message.status);
      			}
      
      			if (message.hasOwnProperty('data')){
      			console.log("[" + self.name + "]" + message.data.PlrStat + " : " + message.data.Station + " : " + message.data.Said + " : " + message.data.volume);
      			self.sendData({"PlrStat": message.data.PlrStat, "TrkNxt":message.data.TrkNext, "Station": message.data.Station, "Said": message.data.Said, "volume": message.data.volume});
      			}
      		});
      
      	},
      
      });
      

      What am I doing wrong? Sorry about the formatting.

      posted in Troubleshooting
      G
      grantc66
    • RE: Snowbound on node.js

      Node_helper.js runs a pythonshell when getting a notification from the module.

      Ah! It’s not running in the same environment as it does from the command line.

      Is that fixable? Would running it as a child process help?

      posted in Troubleshooting
      G
      grantc66
    • Snowbound on node.js

      I’ve created a python script to interface with the mirror to do a follow a few simple instruction (play internet radio, adjust volume etc). This works well, but it is a bit irritating that every phone in the local area tries to respond as well as the mirror.

      So I integrated snowboy as a front end to activate Google’s listener. This works perfectly when running from a terminal but doesn’t respond when the python is called from the node helper.

      Can somebody explain why the same code doesn’t run when it’s initiated from the node helper?

      Sorry if it’s a bit of a basic question. I’ve tried googling but I can’t find anything that appears relevent.

      posted in Troubleshooting
      G
      grantc66
    • RE: Black screen after MM v2.4.0 update.

      Not sure if I’m having the same issue, stupidly updated electron as npm was claiming 1.7.13 had a critical vulnerability (after installing MMM-voice) Then got the backscreen issue. rolled back electron to 1.7.13 & the issue persists.

      Node v9.11.1
      npm 6.1.0

      Thought I’d uploaded the log file but not sure if others can see it. That snippet below is the first error after ALL_MODULES_STARTED

      13:01:19.440 main.js:40 Uncaught TypeError: Cannot read property ‘appendChild’ of undefined
      at main.js:40
      at Array.forEach ()
      at createDomObjects (main.js:24)
      at Object.modulesStarted (main.js:471)
      at startModules (loader.js:59)
      at loader.js:40
      at HTMLLinkElement.stylesheet.onload (loader.js:203)
      (anonymous) @ main.js:40
      createDomObjects @ main.js:24
      modulesStarted @ main.js:471
      startModules @ loader.js:59
      (anonymous) @ loader.js:40
      stylesheet.onload @ loader.js:203

      13:01:20.056 TypeError: Cannot read property ‘getElementsByClassName’ of null
      at moduleNeedsUpdate (main.js:176)
      at main.js:144
      at Promise ()
      at updateDomWithContent (main.js:137)
      at main.js:119
      at
      Promise rejected (async)
      (anonymous) @ main.js:121
      Promise resolved (async)
      (anonymous) @ main.js:118
      updateDom @ main.js:109
      updateDom @ main.js:514
      updateDom @ module.js:358

      Any pointers as to how to get it working again? It was working perfectly before MMM-voice & buggering around with electron.
      Tried a fresh install with the same result 😞

      posted in Troubleshooting
      G
      grantc66
    • RE: MMM-Pir-Sensor - Hue lights control

      I found it to slow running it through the mm, maybe cause I’m running it from a pi0.
      So I run the PIR python script (it also does the led strips) as a background task outside of mm enabled at boot via crontab.
      It’s more responsive and seems to use less resources.

      posted in Troubleshooting
      G
      grantc66
    • RE: Switch off the display - how to ?

      Not sure if I understand the issue.

      You want to inhibit the screensaver?

      I have a script in the startup:

      #!/bin/sh
      xset -dpms # disable DPMS (Energy Star) features.
      xset s off # disable screen saver
      xset s noblank # don’t blank the video device
      unclutter & # loose the cursor

      This works for me on a Pi0 which doesn’t have a desktop, might be different if you have a console loaded at boot.
      Others have mentioned installing the screensaver app and using that to inhibit the display blanking.

      If you want to switch the display from a phone, try RasPiCheck (available from Google Play) & set up a couple of console commands:

      vcgencmd display_power 1 # for on
      vcgencmd display_power 0 # for off

      you’ll need SSH switched on in the Pi config & know the Pi ip-address.

      posted in Troubleshooting
      G
      grantc66