Receiving contiinuous output from python spawn child process not working
Asked Answered
S

1

2

I am attempting to stream output from a weighing scale that is written in python. This program (scale.py) runs continuously and prints the raw value every half second.

import RPi.GPIO as GPIO
import time
import sys

from hx711 import HX711

def cleanAndExit():
    print "Cleaning..."
    GPIO.cleanup()
    print "Bye!"
    sys.exit()

hx = HX711(5, 6)

hx.set_reading_format("LSB", "MSB")

hx.reset()
hx.tare()

while True:
    try:
        val = hx.get_weight(5)
        print val

        hx.power_down()
        hx.power_up()
        time.sleep(0.5)
    except (KeyboardInterrupt, SystemExit):
        cleanAndExit()

I am trying to get each raw data point in a separate NodeJs program (index.js located in the same folder) that is printed by print val. Here is my node program.

var spawn = require('child_process').spawn;
var py = spawn('python', ['scale.py']);

py.stdout.on('data', function(data){
  console.log("Data: " + data);
});

py.stderr.on('data', function(data){
  console.log("Error: " + data);
});

When I run sudo node index.js there is no output and the program waits into perpetuity.

My thought process is that print val should put output into stdout stream and this should fire the data event in the node program. But nothing is happening.

Thanks for your help!

Schema answered 20/4, 2018 at 18:2 Comment(0)
S
10

By default, all C programs (CPython included as it is written in C) that use libc will automatically buffer console output when it is connected to a pipe.

One solution is to flush the output buffer every time you need:

print val
sys.stdout.flush()

Another solution is to invoke python with the -u flag which forces it to be unbuffered:

var py = spawn('python', ['-u', 'scale.py']);
Sobranje answered 20/4, 2018 at 18:23 Comment(3)
AWESOME! I was so close yet so far. Thank you for explaining the buffer, I had no idea that was the behavior. FYI, The first solution worked out better for me as the second was producing a blank write after each data point. Thanks!Schema
that's a really great answer for what I was looking for about 3 hours or so! I created a standalone using pyinstaller, but I had to use sys.stdout.flush() for it to work, so really thank you! though It would be nice of you if you know a way so that the pyinstaller would use the -u argument by default (seems the argument not working with it)Nitrite
I can't tell you how happppy I am, I have been struggling with this for days, and finally finalllllllly I found this answer, Thanks a lot, works like charm!!!Divagate

© 2022 - 2024 — McMap. All rights reserved.