summaryrefslogtreecommitdiff
path: root/fsm/traffic_light_fsm.py
blob: 6c0b3c17d9a4412d2f37af0afa05d3ecc772bf20 (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
91
92
93
from transitions import Machine
from graphviz import Digraph
import enum
from datetime import datetime
import os
import time

class Matter(object):
    pass


def hunger_state():
    # The states
    states = ['hungry', 'satisfied', 'full', 'sick']

    # And some transitions between states.
    transitions = [{'trigger': 'eat', 'source': 'hungry', 'dest': 'satisfied'},
                   {'trigger': 'eat', 'source': 'satisfied', 'dest': 'full'},
                   {'trigger': 'eat', 'source': 'full', 'dest': 'sick'},
                   {'trigger': 'rest', 'source': ['satisfied', 'full', 'sick'],
                    'dest': 'hungry'}]

    # Initialize
    machine = Matter()
    fsm = Machine(machine, states=states, transitions=transitions, initial=states[0],
                  auto_transitions=False)
    return fsm

class States(enum.Enum):
    ERROR = 0
    RED = 1
    YELLOW = 2
    GREEN = 3

def traffic_light_fsm():


    transitions = [
                   ['timer_le_20', States.RED, States.RED],
                   ['timer_eq_20', States.RED, States.GREEN],
                   ['timer_le_15', States.GREEN, States.GREEN],
                   ['timer_eq_15', States.GREEN, States.YELLOW],
                   ['timer_le_5', States.YELLOW, States.YELLOW],
                   ['timer_eq_5', States.YELLOW, States.RED],
               ]

    fsm = Machine(states=States,
                  transitions=transitions,
                  initial=States.RED,
                  auto_transitions=False)
    return fsm


def vis(fsm, name):
    dot = Digraph(comment=name)

    for label, event in fsm.events.items():
        for event_transitions in event.transitions.values():
            for transition in event_transitions:
                dot.edge(transition.source, transition.dest, label)
    dot.render('{}.dot'.format(name))


if __name__ == '__main__':
    fsm = traffic_light_fsm()
    vis(fsm, 'traffic-light')
    start = datetime.now()

    while True:
        time.sleep(1)
        cur = datetime.now()
        duration = cur - start
        duration_secs = duration.seconds % 40
        if 0 < duration_secs < 20:
            if fsm.state == States.YELLOW:
                fsm.timer_eq_5()
            fsm.timer_le_20()
            print(cur, fsm.state)
        elif duration_secs == 20:
            fsm.timer_eq_20()
            print(cur, fsm.state)
        elif 20 < duration_secs < 35:
            fsm.timer_le_15()
            print(cur, fsm.state)
        elif duration_secs == 35:
            fsm.timer_eq_15()
            print(cur, fsm.state)
        elif duration_secs < 40:
            fsm.timer_le_5()
            print(cur, fsm.state)
        else:
            fsm.timer_eq_5()
            print(cur, fsm.state)