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

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 Jan 20, 2019, 1:57 PM

    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 Jan 20, 2019, 3:21 PM Reply Quote 0
    • S Offline
      sdetweil @grantc66
      last edited by Jan 20, 2019, 3:21 PM

      @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 Jan 23, 2019, 10:18 AM

        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
        1 / 1
        • First post
          3/3
          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