Skip to content
Advertisement

How to get the value of a python script I run through ssh

I am using 2 raspberry pi and each of them has a camera connected. I am trying to run, from the first pi, a script to get the video feed of the second one.
And for that, I would need the value my function returns through ssh.

With a simple example :
slaveScript.py

def run():
    return "hello there"

if __name__ == '__main__':
    run()

masterScript.py

import pexpect

try:
    # ssh connection
    child = pexpect.spawn('ssh -X pi@pislave.local')
    child.expect('pi@pislave.local's password:', timeout=10) 
    child.sendline('pi')
    child.expect('$')

    # run script
    child.sendline('python3 slaveScript.py run')
    cap = child.read() # error here
    print(cap)
    
except pexpect.ExceptionPexpect as e:
    print(str(e))

I would like, for this example to get “hello there”. How can I get it? Is there a pexpect method I can use?

In context with the cameras :
SlaveScript.py

import cv2

def run():
    return cv2.VideoCapture(0)

if __name__ == '__main__':
    run()

MasterScript.py

import pexpect
import cv2

try:
    # ssh connection
    child = pexpect.spawn('ssh -X pi@pislave.local')
    child.expect('pi@pislave.local's password:', timeout=10) 
    child.sendline('pi')
    child.expect('$')

    # run script to read and show the video feed
    while True:
        child.sendline('python3 SlaveScript.py')
        cap = child.read()
        ret, frame = cap.read()
        
        cv2.imshow('slaveCam', frame)


except pexpect.ExceptionPexpect as e:
    print(str(e))

I know that it works if I put the lines from while True to cv2.imshow in the slave script. I have a window opening and a video feed of around 1 image every 3 seconds (I don’t care about performance).
However, the video feed will have to be implemented inside a kivy GUI, so I need to get the frame in my master script so that I can put it in a texture in kivy.

Is there any way to do it?

Advertisement

Answer

I think you are on the wrong track with pexpect. You should be using password-less login by copying your public RSA key to the slave device – then you can get rid of all the awkwardness of pexpect.

Also, I would consider using Redis. It is very fast, and lightweight and it serves integers, strings, lists, sets, hashes from memory (RAM) across a network.

Simply stuff the frames of video in Redis on the slave, either as JPEGs, or PNGs or Numpy arrays and call it latestFrame. That looks like:

redis.set('latestFrame', frame)

On the other machine, just grab latestFrame from Redis and display it. That looks like:

frame = redis.get('latestFrame')

Example here.

Advertisement