aboutsummaryrefslogtreecommitdiff
path: root/dial.py
blob: 0d14a326592d5f44fd6aca8aeb891949b053dceb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from datetime import datetime, timedelta
import time
import RPi.GPIO as GPIO
import threading
import events

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):
        # After REST_TIME seconds, assume the rotary dial stopped spinning
        return datetime.now() - rest_start > timedelta(seconds=REST_TIME)


class DialManager:
    def __init__(self, phone_held, phone_hung_up):
        self.sequence = []
        self.update = datetime.now()
        self._load_sequences(phone_held, phone_hung_up)

    def _load_sequences(self, phone_held, phone_hung_up):
        self.sequences = {
                0: events.OperatorEvent(self, phone_held, phone_hung_up),
                1: events.WeatherEvent(self, phone_held, phone_hung_up),
                2: events.TimerEvent(self, phone_held, phone_hung_up),
                4: {1: {1: events.DirectoryEvent(self, phone_held, phone_hung_up)}},
                7: events.FortuneEvent(self, phone_held, phone_hung_up),
            }
        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)

    def clear_sequence(self):
        self.sequence = []