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.

    Running Python under node.js

    Scheduled Pinned Locked Moved General Discussion
    3 Posts 3 Posters 779 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.
    • G Offline
      grantc66
      last edited by

      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.

      S 1 Reply Last reply Reply Quote 0
      • S Offline
        sdetweil @grantc66
        last edited by

        @grantc66 cool, thanks…

        for node, you could have spun off a long running python app,
        and added data.on() event handlers in javascript node_helper to get called each time the python app wrote to the console (stdout)… which could have been json data, or whatever text you liked

        const {spawn} = require('child_process')
        
        const child = spawn('pwd');
        
        child.stdout.on('data', (data) => {
          console.log(`child stdout:\n${data}`);
        });
        
        child.stderr.on('data', (data) => {
          console.error(`child stderr:\n${data}`);
        });
        

        Sam

        How to add modules

        learning how to use browser developers window for css changes

        1 Reply Last reply Reply Quote 0
        • T Offline
          timpaines
          last edited by

          Node js is one of the powerful tools of programming and using this if you are working on python it help you a lot. printer offline fix helped me to know more about python.

          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