¿ªÔÆÌåÓý

Locked Script Closing Serial Ports Question


 

Hi,
Question: I have a functioning script cal it scriptA working well using a serial port successfully as the input and output stream.
If I kill the script, the port is left open.
Is there a way to run a second script (call it scriptB) that can close the I/O streams and the previously opened port successfully?
The port is static, ie. the port can be explicitly known to both scripts.

The fact that the port remains open, prevents scriptA from being re-run.
Alternatively, can scriptA check to see if the port is already open and re-acquire it?

Any help, including specific scripts or pointers in the right direction would be much appreciated.
Thanks. Have fun!? :-)
Best regards,
Geoff Bunza


 

You have to leave a reference to the SerialPort object (I.e. the thing that was returned when you called ¡°open(..)¡± ) somewhere you can get it. Once you have that, you can call ¡°close¡± on it whenever you want;

I.e. if you have

self.port = self.portID.open("JMRI", 50)

you need to keep that object around so you can later do

self.port.close()


Or store it in a global variable or whatever.

Bob

On Aug 11, 2018, at 8:07 PM, Geoffb <gbglacier@...> wrote:

Hi,
Question: I have a functioning script cal it scriptA working well using a serial port successfully as the input and output stream.
If I kill the script, the port is left open.
Is there a way to run a second script (call it scriptB) that can close the I/O streams and the previously opened port successfully?
The port is static, ie. the port can be explicitly known to both scripts.

The fact that the port remains open, prevents scriptA from being re-run.
Alternatively, can scriptA check to see if the port is already open and re-acquire it?

Any help, including specific scripts or pointers in the right direction would be much appreciated.
Thanks. Have fun! :-)
Best regards,
Geoff Bunza
--
Bob Jacobsen
rgj1927@...


 

Hi Bob,
Thanks much! That was simple and worked perfectly (and I should have thought of it myself!).
Much appreciated.
Have fun!? :-)
Best regards,
Geoff Bunza


 

Hello Geoff and thank you Bob. I also use the serial port in scripts. Is it possible that you can publish your fix? I offen suffer the same problem but my programming skill is not quite as good s I would like it to be. But I can follow the bouncing ball.

Dave,
Brisbane, Australia.


 

Hi Dave,
As requested, here is an example of how I close the serial port. Also note that the "return 0" also terminates the script:
if closing_test == 1 :
??? ??? ?print "Script Ends"
??? ??? ?self.inputStream.close()
??? ??? ?self.outputStream.close()
??? ??? ?self.port.close()
??? ??? ?return 0
I started with Bob Jacobsen's SerialPortDevice.py in the JMRI release as a learning tool and template. (Thanks Bob!)
The test above would be in the equivalent of the handle(self)

If you followed this thread before, I was also interested in using a second script to forcibly close the port too.
to accomplish this (again with a great suggestion from Bob!) you create a global variable which can be used to refer to the
open port. So again referring to SerialPortDevice.py by structure, you would have in your original script:
??? def __init__(self, portname) :
??? global extport
??? ...
??? extport = self.port = self.portID.open("JMRI", 50)
??? ...

And here is my ForcePortClose.py? script to close the specific port and terminate:

import jarray
import jmri
import purejavacomm

class SerialCloseM(jmri.jmrit.automat.AbstractAutomaton) :
??? # ctor starts up the serial port
??? def __init__(self, portname) :
??????? global extport
??????? self.portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname)
??????? extport.close()
??????? return
??? # init() is the place for your initialization
??? def init(self) :
??????? return
??? # handle() is called repeatedly until it returns false.
??? def handle(self) :
????????? return 0
??? def write(self, data) :
??????? return
??? def flush(self) :
??????? self.outputStream.flush()
??????? return
# create one of these; provide the name of the serial port
a = SerialCloseM("COM13")
# set the thread name, so easy to cancel if needed
a.setName("ForcePortClose script")
# start running
a.start();


Also, FYI, what I found is that using the second script to close the port while the first script is still running
will force a portnotopen exception and terminate the first script as well. This, for me, was a desirable side effect!

An educational note: When Bob suggested using a global variable I was, at first, surprised that a global variable would
exist beyond the scope of the script. But one should realize that the global scope is JMRI not just one script. That is,
any script runs inside the global JMRI scope, and my own thinking was myopically focused on a single script.
Score another point for the beauty and the complexity that is JMRI.

I will be publishing an app soon that will incorporate these features and add another that you might find useful too.
More to come...
'Hope this helps. Have fun!? :-)
Best regards,
Geoff Bunza
scalemodelanimation.com


 

Thank you Geoff, as always very well written and I understood it all. Thank you.

I am always interested in your stuff. I use quite a lot of your projects, broads and ideas with the hobby. I will keep an eye out.

Thank you sir,

Dave,
Brisbane, Australia