From 5b2a3f0da147f17f6ab32af8e3d14fb29de71fd1 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Mon, 12 Jul 2021 20:27:50 -0500 Subject: Fix handler so events cannot be dialed while one is playing, and so events can be terminated --- dial.py | 8 ++++++-- events.py | 26 ++++++++++++++++++++++---- main.py | 9 +++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/dial.py b/dial.py index b6f3dd9..8fc92a9 100644 --- a/dial.py +++ b/dial.py @@ -10,10 +10,12 @@ REST_TIME = 0.3 # seconds DIAL_RESET_TIME = 5 # seconds class DialThread(threading.Thread): - def __init__(self, queue): + def __init__(self, queue, phone_held, processing_event): threading.Thread.__init__(self, args=(), kwargs=None) self.queue = queue self.daemon = True + self.phone_held = phone_held + self.processing_event = processing_event GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP) @@ -37,7 +39,9 @@ class DialThread(threading.Thread): rest_start = datetime.now() pressed = False if self.dial_over(rest_start) and not printed: - self.queue.put(count % 10) # wrap 10 to 0 + # Only add this dial to queue if we should accept numbers at this time + if self.phone_held.is_set() and not self.processing_event.is_set(): + self.queue.put(count % 10) # wrap 10 to 0 count = 0 printed = True time.sleep(0.01) diff --git a/events.py b/events.py index cbd17ea..f177a01 100644 --- a/events.py +++ b/events.py @@ -4,6 +4,17 @@ from config import config import requests from multiprocessing import Process +class SpeakProcess(Process): + def __init__(self, text): + super().__init__() + self.daemon = True + self.text = text + + def run(self): + print("speaking:", self.text) + subprocess.run(["espeak", self.text]) + + class Event(): def __init__(self, dial_manager, phone_held, phone_hung_up): self.dial_manager = dial_manager @@ -17,9 +28,11 @@ class Event(): return "event" def speak(self): - text = self.get_text() - print("speaking:", text) - subprocess.run(["espeak", text]) + process = subprocess.Popen(["espeak", self.get_text()]) + while process.poll() is None: + if self.phone_hung_up.wait(timeout=0.1): + process.terminate() + class FortuneEvent(Event): def get_name(self): @@ -56,7 +69,12 @@ class OperatorEvent(Event): def get_text(self): now = datetime.now() - return f"Right now, it is {now.hour} {now.minute}. Dial 4 1 1 for directory." + nearest_quarter = ((n.minute // 15 + 1) * 15) % 60 + hour = now.hour % 12 + day_half = "A M" + if hour != now.hour: + day_half = "P M" + return f"Right now, it is {hour} {now.minute} {day_half}." class WeatherEvent(Event): diff --git a/main.py b/main.py index db8b983..10d4bb4 100755 --- a/main.py +++ b/main.py @@ -11,18 +11,21 @@ if __name__ == "__main__": queue = Queue() phone_held = Event() phone_hung_up = Event() + processing_event = Event() # start phone as on hook phone_held.clear() phone_hung_up.set() + processing_event.clear() - dial_thread = DialThread(queue) + dial_thread = DialThread(queue, phone_held, processing_event) dial_thread.start() dial_manager = DialManager(phone_held, phone_hung_up) hang_up_thread = HangUpThread(phone_held, phone_hung_up, dial_manager) hang_up_thread.start() - + + print("Ready") while True: try: # Wait for phone to be picked up @@ -35,7 +38,9 @@ if __name__ == "__main__": response = dial_manager.dial(dialed) # If we matched a sequence, play out event if response is not None: + processing_event.set() response.speak() + processing_event.clear() except Exception as e: print(e) -- cgit v1.2.3