Keyboard Shortcuts
Likes
Search
Locked
Problem calling one script from another
#scripting
Could someone please advise why the following python scripts work together in RPi Thonny, but not from within PanelPro.
The script for the initiating programme, testsend.py : import subprocess import sys x=678 print(x) subprocess.run(["python3","testreceive.py", str(x)]) and this is the script for the receiving programme, testreceive.py " import serial import sys if len(sys.argv)>1:
? ? y= int(sys.argv[1])
? ? print(1+ y)
else:
? ? print("no argument received") Thank you in anticipation Toni |
The ¡°subprocess.run¡± line is meant to run sometime as, well, a subprocess. This is attempting to run the 2nd script outside JMRI. It¡¯s not set up for that.
If your goal is to run a separate script file, you can use ¡°execfile(..)¡± to do that. More generally, JMRI¡¯s scripting uses a Python derivative called Jython. The good news is that Jython works with underlying Java code well. The bad news is that it¡¯s Python 2.5, i.e. old, and doesn¡¯t have many of the nice Python packages that can do cool things. There¡¯s been some limited work on using native Python3 for scripting, but that¡¯s really not ready for general use yet. Bob On Dec 10, 2023, at 11:27?PM, Toni Mury <toni@...> wrote:¡ª Bob Jacobsen rgj1927@... |
Hi Bob
I have successfully modified my codes as you suggested however I need the receiving programme to include a serial connection to drive a stepper motor. If I comment out the serial code part as shown below all works well but if I include those lines it does not work. ? Does JMRI not like serial code? If so how could I automatically send commands to the stepper motor. (The stepper motor driver is on a Pico with a USB connection to the RPi but I don¡¯t think the stepper motor is the problem just the serial connection to the Pico.) ? The successful script for the initiating programme, testsend.py is: ? import sys xyz=100 print(xyz) execfile(jmri.util.FileUtil.getExternalFilename("scripts:testreceive.py")) #execfile("testreceive.py") print("data transferred") ? ? The successful script for the receiving programme, testreceive.py? is: ? import sys ¡®¡¯¡¯ import serial port = "/dev/ttyACM2" baudrate = 115200 ser = serial.Serial(port,baudrate) if ser.isOpen(): ? ? print(ser.name + ' is open') ¡®¡¯¡¯ print (xyz+1) Thanks Toni |
You need to use a different Serial library to work within JMRI. For an example of receiving (done with an independent thread to avoid blocking JMRI) and sending, see
jython/SerialPortTest.py Extracting the parts needed to just send: import jmri import purejavacomm # find the port info and open the port print "opening ",portname portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname) port = self.portID.open("JMRI", 50) # set options on port baudrate = 9600 port.setSerialPortParams(baudrate, purejavacomm.SerialPort.DATABITS_8, purejavacomm.SerialPort.STOPBITS_1, purejavacomm.SerialPort.PARITY_NONE) # get I/O connection for later outputStream = port.getOutputStream() print "Port opened OK¡± # to write some characters ´Ç³Ü³Ù±è³Ü³Ù³§³Ù°ù±ð²¹³¾.·É°ù¾±³Ù±ð(¡®´¡¡¯) ´Ç³Ü³Ù±è³Ü³Ù³§³Ù°ù±ð²¹³¾.·É°ù¾±³Ù±ð(¡®µþ¡¯) ´Ç³Ü³Ù±è³Ü³Ù³§³Ù°ù±ð²¹³¾.·É°ù¾±³Ù±ð(¡®°ä¡¯) ´Ç³Ü³Ù±è³Ü³Ù³§³Ù°ù±ð²¹³¾.·É°ù¾±³Ù±ð(¡®°À²Ô¡¯) outputStream.flush() It might be easier to wrap the outputStream in a DataOutputStream which lets you write out strings, integers, etc: dataStream = java.io <>.DataOutputStream(outputStream) dataStream.writeBytes(str(12)) Bob On Dec 11, 2023, at 7:05?PM, Toni Mury <toni@...> wrote:¡ª Bob Jacobsen rgj1927@... |
Hi Bob
I think I might be missing something. I've run the following code which include print statements so I can monitor where it is up to and it seems to stop after the 'portID= ...' line and before the 'port=...' line. The only print results I am getting so far are" portname = ?/dev/ttyACM2 portID = ?purejavacomm.CommPortIdentifier@22dbe717 The code I am running is: import jmri import purejavacomm ? # find the port info and open the port portname = "/dev/ttyACM2" print "portname = " , portname ? portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname) print "portID = ", portID ? port = self.portID.open("JMRI",50) print "testing" ? #set options on port print "setting port options" baudrate = 9600 port.setSerialPortParams(baudrate,purejavacomm.SerialPort.DATABITS_8, purejavacomm.SerialPort.STOPBITS_1, purejavacomm.SerialPort.PARITY_NONE) print "port options set" ? #get I/O connection for later outputStream = port.getOutputStream() ? #to write some characters outputStream.write(str(50)) print("character written") Thanks Toni |
Yes. When I copy, paste and edited that script, I left a ¡°self.¡± in that shouldn¡¯t have been. Change line 11 to
port = portID.open("JMRI",50) (i.e. remove the ¡°self.¡±). In general, if a script hits an error, it¡¯ll put something in the log that refers to the line number, then stop. So that¡¯s a good first place to look. Bob On Dec 12, 2023, at 4:17?PM, Toni Mury <toni@...> wrote:¡ª Bob Jacobsen rgj1927@... |
Thanks Bob, your help and knowledge is really appreciated. I'll now move on to the next step.
Just for interest, the project involves a stepper motor driving ?a 2 track into 5 track traverser. The required traverser position is selected from a layout panel which initiates a logix which then runs this script.? Cheers and Happy Christmas Toni Canberra, Australia |
Happy New Year Bob
Further to our previous discussions I have tailored your code to match the connected Pico port as follows and then created a script as main.py on the Pico to test the process. The Pico (csv file) is showing no signs of receiving the output stream from JMRI and I'm wondering what I'm missing. Are you able to help? The scripts are: # main.py csv_filename = "data.csv" def save_to_csv(data): ? ? with open(csv_filename,"a") as f: ? ? ? ? f.write(data +"\n") while True: ? ? select_result = uselect.select([stdin], [], [], 0) ? ? buffer = '' ? ? while select_result[0]: ? ? ? ? input_character = stdin.read(1) ? ? ? ? if input_character != ',': ? ? ? ? ? ? buffer += input_character ? ? ? ? else: ? ? ? ? ? ? save_to_csv(buffer) ? ? ? ? ? ? buffer='' ? ? select_result = uselect.select([stdin], [], [], 0) import jmri import purejavacomm print "purejavacomm started" # find the port info and open the port portname = "/dev/ttyACM2" print "portname = " , portname portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname) print "portID = ", portID port = portID.open("JMRI",50) #set options on port print "setting port options" baudrate = 9600 print "baudrate = ",baudrate port.setSerialPortParams(baudrate,purejavacomm.SerialPort.DATABITS_8, purejavacomm.SerialPort.STOPBITS_1, purejavacomm.SerialPort.PARITY_NONE) print "port options set" #get I/O connection for later outputStream = port.getOutputStream() print "port opened OK" #to write some characters outputStream.write('A') outputStream.write('B') outputStream.write('C') outputStream.write('\n') outputStream.flush() #close the port time.sleep(2) port.close() print "port closed" ? ? |
I don¡¯t fully understand your Pico script, but it looks like it¡¯s reading from stdin instead of from a serial port.
Does the Pico¡¯s version of Python have PySerial? Bob On Jan 11, 2024, at 9:28?PM, Toni Mury <toni@...> wrote:¡ª Bob Jacobsen rgj1927@... |
All I know is what I¡¯ve read here:
But it looks like it would work. Bob On Jan 14, 2024, at 6:06?PM, Toni Mury <toni@...> wrote:¡ª Bob Jacobsen rgj1927@... |