Search code examples
pythonpython-3.xarduinobackground-process

How to Keep my script running in the background


I am making a python script that reads data from the serial port sent from an arduino and inserts it on a database. I am using java to make a gui that graphs the data. I want to keep my python script running in the background when the java gui is opened, but I want to close the python script as soon as the java gui is closed. Below is my python code, I haven't implemented the java gui yet.

import serial, sqlite3

conn=sqlite3.connect("ProyectoFinal1.db")
c=conn.cursor()
ser = serial.Serial('COM5', 9600)

def tableCreate():
    c.execute("CREATE TABLE Temperatura(ID INT,valor INT,Fecha TIMESTAMP)")
    c.execute("CREATE TABLE Humedad(ID INT,valor INT,Fecha TIMESTAMP)")

def dataEntry(tabla,valor):
    c.execute("INSERT INTO %(tabla)s (Fecha,valor) VALUES(CURRENT_TIMESTAMP,%(valor)s)"%{"tabla":tabla,"valor":valor})
    conn.commit()


def serialRead():
   ser = serial.Serial("/dev/ttyUSB0")
   for data in ser.readline():
      if data:
        serial=data

   return serial

def parse(toParse):
    toParse=toParse.split(" ")
    humidity=toParse[0]
    temperature=toParse[1]
    toParse=[humidity,temperature]
    return toParse


while True:
  temperatura=parse(ser.readline())[1]
  humedad=parse(ser.readline())[0]

  dataEntry("Temperatura",temperatura)
  dataEntry("Humedad",humedad)

  print (humedad)

  print (temperatura)

Solution

  • One cross-platform way to figure out if a parent process as exited is to open a pipe between the processes and wait for it to close. The following example starts a thread in the child process that waits for stdin to close and then closes the serial port which then exits the main loop's readline.

    For this to work, the parent java script needs to open a pipe and use that for the python process stdin. I don't know how to do that part but since you didn't show the java code I'll pretend that's the reason I didn't include it. This has an additional advantage in that the parent java code could gracefully close the child simply by sending a "\n" down the pipe.

    import threading
    import sys
    
    # add everything before your while loop here
    
    def parent_exit_detector(ser_to_close, pipe_to_wait):
        """Wait for any data or close on pipe and then close the
        serial port"""
        try:
            pipe_to_wait.read(1)
        finally:
            ser.close()
    
    _exit_detector_thread = threading.Thread(target=parent_exit_detector,
        args=(ser, sys.stdin))
    _exit_detector_thread.isDaemon = True
    
    
    # add the while loop here