Search code examples
pythonflaskbackground-process

Python : starting background process from background process


I'm having a bit of an issue, and my many tests/searches have led me nowhere so far.

I have a Flask application giving a GUI for a small alarm system running on a raspberry pi. The GUI allows to start the alarm (motion sensors on the GPIO pins, for now) as a background process. This runs fine, in case of a detection it sends an email. I'm trying to add a method that will play a siren sound (or a black metal song at 100 db, haven't decided yet :p ). The method itself is in a class and works fine, I can activate/deactivate it as another background process from the GUI.

However, I am unable to have it triggered automatically by the alarm process. Not sure why, I have no error, it just doesn't fire:

class Alarm(Process):

  def __init__(self):
      super().__init__()
      self.exit = Event()


  def shutdown(self):
      self.exit.set()

  def run(self):

      Process.__init__(self)

      #code
      #if motion detected sendmail, and run the siren:

      siren = Siren()  #actually, problem here: I need to import the class 
                       #and declare this in the main Flask app file, so as 
                       #to be able to control it from the GUI. Apparently I 
                       #can't declare it in both python files (sounds 
                       #obvious though)
      siren.start()

      #then keep looping

and the Siren class is similar:

class Siren(Process):
    def __init__(self):
        super().__init__()

    def run(self):

        Process.__init__(self)

        #code using pyaudio

I'm guessing my very basic understanding of classes and methods is the culprit here. I've also tried to use events, so instead of siren.start() I'd have something like e = Event() and e.set(), but I couldn't manage to run the Siren class in the background and have it pick that event up with e.wait().

Anyone can point me in the right direction?

Thanks!


Solution

  • You should not be calling Process.__init__ from Alarm.run! You are already doing that in Alarm.__init__

    Process.__init__(self) is exactly the same as super().__init__()

    update

    Does this help:

    import threading
    import time
    
    class Alarm(threading.Thread):
    
    
    
        def run(self):
    
            #code
            #if motion detected sendmail, and run the siren:
    
            siren = Siren()  #actually, problem here: I need to import the class 
                             #and declare this in the main Flask app file, so as 
                             #to be able to control it from the GUI. Apparently I 
                             #can't declare it in both python files (sounds 
                             #obvious though)
            siren.start()
    
    
            #then keep looping
            for x in range(20):
                print ".",
                time.sleep(1)
            siren.term()
            siren.join()
    
    
    
    class Siren(threading.Thread):
    
        def run(self):
    
            self.keepRunning=True;
    
            while self.keepRunning:
                print "+",
                time.sleep(1)
    
        def term(self):
            self.keepRunning=False
    
    if __name__ == '__main__':
        alarm = Alarm()
        alarm.run()
    

    output:

    +. + . .+ . + +. +. . + . + . + . + + . + . + . + . + . + . + . + . +. +. +