From a981a50b0597498a9fc92249f93f940998455ca3 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Sun, 11 Jul 2021 04:03:59 +0100 Subject: Initial commit --- dial.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 24 +++++++++++++++++ phone.py | 16 +++++++++++ 3 files changed, 132 insertions(+) create mode 100644 dial.py create mode 100755 main.py create mode 100644 phone.py diff --git a/dial.py b/dial.py new file mode 100644 index 0000000..c5f556f --- /dev/null +++ b/dial.py @@ -0,0 +1,92 @@ +from datetime import datetime, timedelta +import time +import RPi.GPIO as GPIO +import threading + +BUTTON_GPIO = 25 +REST_TIME = 0.3 # seconds +DIAL_RESET_TIME = 5 # seconds + +class DialThread(threading.Thread): + def __init__(self, queue): + threading.Thread.__init__(self, args=(), kwargs=None) + self.queue = queue + self.daemon = True + + GPIO.setmode(GPIO.BCM) + GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP) + + def run(self): + pressed = True + rest_start = datetime.now() + count = 0 + printed = True + + while True: + # button is pressed when pin is LOW + if not GPIO.input(BUTTON_GPIO): + if not pressed: + count+=1 + pressed = True + printed = False + # button not pressed (or released) + else: + if pressed: + rest_start = datetime.now() + pressed = False + if self.dial_over(rest_start) and not printed: + self.queue.put(count % 10) # wrap 10 to 0 + count = 0 + printed = True + time.sleep(0.01) + + def dial_over(self, rest_start): + return datetime.now() - rest_start > timedelta(seconds=REST_TIME) + + +class DialManager: + def __init__(self): + self.sequence = [] + self.update = datetime.now() + self._load_sequences() + + def _load_sequences(self): + self.sequences = { + 0: "operator", + 1: { + 2: "test_multiple" + }, + 2: "weather", + 3: "horrorscope", + 4: "", + 5: "", + 6: "", + 7: "fortune", + 8: "", + 9: "" + } + print(self.sequences) + + def dial(self, number): + if datetime.now() - self.update > timedelta(seconds=DIAL_RESET_TIME): + self.sequence = [] + self.sequence.append(number) + match = self.match_sequence() + print(self.sequence, match, sep="\t") + if match is not None: + self.sequence = [] + self.update = datetime.now() + return match + + def match_sequence(self): + def recursive_find(sequence, sequences): + if not sequence: + return None + digit = sequence[0] + if not digit in sequences: + return None + if isinstance(sequences[digit], dict): + return recursive_find(sequence[1:], sequences[digit]) + return sequences[digit] + return recursive_find(self.sequence, self.sequences) + diff --git a/main.py b/main.py new file mode 100755 index 0000000..ec3d0b6 --- /dev/null +++ b/main.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from dial import DialManager, DialThread +from phone import PhoneManager + +from time import sleep +from queue import Queue + +if __name__ == "__main__": + queue = Queue() + dial_thread = DialThread(queue) + print("starting thread") + dial_thread.start() + + dial_manager = DialManager() + phone_manager = PhoneManager() + + print("main loop") + while True: + dialed = queue.get(block=True) + response = dial_manager.dial(dialed) + if response is not None: + phone_manager.handle_event(response) + diff --git a/phone.py b/phone.py new file mode 100644 index 0000000..59b9cfb --- /dev/null +++ b/phone.py @@ -0,0 +1,16 @@ +import subprocess + +class PhoneManager: + def handle_event(self, event): + print("handling event", event) + if event == "fortune": + res = subprocess.run(["fortune"], stdout=subprocess.PIPE) + output = res.stdout.decode("utf-8") + self.speak(output) + else: + self.speak(event) + + + def speak(self, text): + print("speaking:", text) + subprocess.run(["espeak", text]) -- cgit v1.2.3