1

First of all, I'm using Ubuntu 20.04 and Python 3.8. I would like to run a program that takes command line inputs. I managed to start the program from python with the os.system() command, but after starting the program it is impossible to send the inputs. The program in question is a product interface application that uses the CubeSat Space Protocol (CSP) as a language. However, the inputs used are encoded in a .c file with their corresponding .h header.

In the shell, it looks like this: starting the program

In python, it looks like this:

import os
os.chdir('/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1')
os.system('./waf')
os.system('./build/csp-client -k/dev/ttyUSB1')
os.system('cmp ident') #cmp ident is typically the kind of command that does not work on python

The output is the same as in the shell but without the "cmp ident output", that is to say it's impossible for me to use the csp-client#

As you can probably see, I'm a real beginner trying to be as clear and precise as possible. I can of course try to give more information if needed. Thanks for your help !

BigPhac
  • 13
  • 3
  • I know nothing about CSP, by the way... do you mean you want to write a Python script that sends a few CSP commands that you already know ahead of time? Or do you mean you want to write a Python script that asks you for input, reads what you type and passes it to CSP and shows you the result? What is `waf`? What is the command you sent? Is something attached to a USB port? What? – Mark Setchell Nov 12 '21 at 14:53
  • In order to see how your program works, can you try running it non-interactively? So, if the command you want send is `cmp ident` can you run `echo "cmp ident" | csp-client -k/dev/ttyUSB1` and see if that works adequately? – Mark Setchell Nov 12 '21 at 14:56
  • I gave you too little information it's my fault : I'm using a nanosatellite imager that uses CSP as protocol, and this imager is controlled thanks to command lines (for example, the command "nanocam snap" will snap a picture). Of course, these commands are encoded in a C file with its corresponding header. So, a RS232-to-USB converter is plugged in the USB1 port. Waf is a Python based build system (https://waf.io/book/). Regarding Python, the final code aims at pressing a button in a GUI that would take a picture, without using command lines, but for now I just cannot access to the cap-client# – BigPhac Nov 13 '21 at 13:56
  • I just tried to run what you told me to, it does not work with this exact command, BUT it works with `echo "cmp ident" | ./csp-client -k/dev/ttyUSB1` however I don't really see how could it help me but I'm gonna think about it – BigPhac Nov 13 '21 at 14:08
  • What command do you type to exit `csp-client` please? – Mark Setchell Nov 13 '21 at 16:07
  • I don't know what you're trying to do, but I would probably recommend that you compile CSP with the python bindings enabled. (using `--enable-python3-bindings` in the WAF command). With this enabled, you can build your application entirely in Python. Here is an example CSP CLI that I made for a Cubesat project: https://github.com/AlbertaSat/ex2_ground_station_software/blob/master/src/CSPHandler.py – Andrew Rooney Dec 21 '22 at 18:00

2 Answers2

1

It sounds like the pexpect module might be what you're looking for rather than using os.system it's designed for controlling other applications and interacting with them like a human is using them. The documentation for it is available here. But what you want will probably look something like this:

import pexpect
p = pexpect.spawnu("/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client -k/dev/ttyUSB1")
p.expect("csp-client")
p.sendline("cmp indent")
print(p.read())
p.close()
theAlex
  • 48
  • 6
0

I'll try and give you some hints to get you started - though bear in mind I do not know any of your tools, i.e. waf or csp-client, but hopefully that will not matter.

I'll number my points so you can refer to the steps easily.


Point 1

If waf is a build system, I wouldn't keep running that every time you want to run your csp-client. Just use waf to rebuild when you have changed your code - that should save time.


Point 2

When you change directory to /home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1 and then run ./build/csp-client you are effectively running:

/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client -k/dev/ttyUSB1

But that is rather annoying, so I would make a symbolic link to that that from /usr/local/bin so that you can run it just with:

csp-client -k/dev/ttyUSB1

So, I would make that symlink with:

ln -s /home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client  /usr/local/bin/csp-client

You MAY need to put sudo at the start of that command. Once you have that, you should be able to just run:

csp-client -k/dev/ttyUSB1

Point 3

Your Python code doesn't work because every os.system() starts a completely new shell, unrelated to the previous line or shell. And the shell that it starts then exits before your next os.system() command.

As a result, the cmp ident command never goes to the csp-client. You really need to send the cmp ident command on the stdin or "standard input" of csp-client. You can do that in Python, it is described here, but it's not all that easy for a beginner.

Instead of that, if you just have aa few limited commands you need to send, such as "take a picture", I would make and test complete bash scripts in the Terminal, till I got them right and then just call those from Python. So, I would make a bash script in your HOME directory called, say csp-snap and put something like this in it:

#/bin/bash

# Extend PATH so we can find "/usr/local/bin/csp-client"
PATH=$PATH:/usr/local/bin

{
   # Tell client to take picture
   echo "nanoncam snap" 
   # Exit csp-client
   echo exit
} | csp-client -k/dev/ttyUSB1

Now make that executable (only necessary once) with:

chmod +x $HOME/csp-snap

And then you can test it with:

$HOME/csp-snap

If that works, you can copy the script to /usr/local/bin with:

cp $HOME/csp-snap /usr/local/bin

You may need sudo at the start again.

Then you should be able to take photos from anywhere just with:

csp-snap

Then your Python code becomes easy:

os.system('/usr/local/bin/csp-snap')
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432